2012-11-06 1 views
10

Quelle est la bonne façon d'ajouter des objets dans NSMutableArray qui est fortement défini par la propriété.Quelle est la bonne façon d'éviter de conserver le cycle pendant l'utilisation des blocs

[tapBlockView setTapBlock:^(UIImage* image) { 
    [self.myImageArray addObject:image]; // self retain cycle 
} 

Si je créerai faible quelque chose de référence comme

__weak NSMutableArray *array = self.myImageArray; 
[tapBlockView setTapBlock:^(UIImage* image) { 
    [array addObject:image]; // If I will do this then how will I update original Array ? 
} 

J'ai aussi essayé

__weak id weakSelf = self; 
[tapBlockView setTapBlock:^(UIImage* image) { 
    [weakSelf storeImageInaNewMethod:image]; // Calling SToreImageInaNewMethod 
} 

et

-(void)storeImageInaNewMethod:(UIImage*)image { 
    [self.myImageArray addObject:image]; // This again retaining cycle 
} 

Quelle est la bonne façon de mettre à jour l'objet original défini par la propriété?

+0

Les blocs sont comme fonction pointers.Can't vous définissez simplement le bloc à zéro lorsque vous n'avez pas en avez plus besoin? –

Répondre

8

Essayez une combinaison de la 2e et 3e.

__weak id weakSelf = self; 
[tapBlockView setTapBlock:^(UIImage* image) { 
    [weakSelf.myImageArray addObject:image]; 
} 
+0

Notez que ceci n'est valable que si vous utilisez weakSelf sur la première ligne du bloc, si vous faites autre chose en premier, alors vous avez besoin de la réponse de Kaan. – malhal

0

Vos deuxième et troisième semblent corrects. La seconde fonctionne parce que vous n'avez pas créé de copie du tableau, ce qui pointe toujours vers la copie d'origine. Le troisième fonctionne parce que la référence à soi est faible.

+0

La 2ème ne fonctionne que si self.myImageArray renvoie une référence directe à l'ivar. Ce n'est peut-être pas une hypothèse sûre. – rmaddy

+0

Vrai, c'est un bon point –

12

Après la réponse de Maddy - c'est de 2012 conférence WWDC sur GCD et la programmation asynchrone:

__weak MyClass *weakSelf = self; 

[tapBlockView setTapBlock:^(UIImage* image) { 
    __strong MyClass *strongSelf = weakSelf; 
    if(strongSelf) { 
     [strongSelf.myImageArray addObject:image]; 
    } 
}]; 
+0

Je ne comprends pas pourquoi vous changez encore en __strong? Je suppose que seul ce code est suffisant? [weakSelf.myImageArray addObject: image]; – Tariq

+6

La raison de la conversion en '__strong' est de garantir que si' weakSelf' est encore vivant quand la première ligne du bloc est exécutée, elle continuera à vivre pendant le reste de l'exécution du bloc. –

+0

Si vous activez les avertissements alors vous verrez pourquoi le __strong est nécessaire: Une variable faible peut disparaître à tout moment, y compris au milieu de l'appel weakSelf.myImageArray qui causera sûrement des problèmes. – gnasher729

1

Dans votre cas, il vous suffit de faire référence à un tableau qui est référencé par self, donc:

NSMutableArray *array = self.myImageArray; 
[tapBlockView setTapBlock:^(UIImage* image) 
          { 
          [array addObject:image]; // No cycle 
          }]; 

Fonctionne bien fourni que self.myImageArray ne renvoie pas différentes références de tableau à différer temps fois. Il n'y a pas de cycle: l'objet courant référence le tableau et le bloc, et à son tour le bloc fait référence au tableau.

Si self.myImageArray ne renvoie différentes références de tableau en différents temps utilisent alors une référence faible à self, votre cas 3.

Questions connexes