Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the proper way to avoid Retain Cycle while using blocks

What is the proper way to add objects in NSMutableArray which is strongly defined by property.

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

If I will create weak reference something like

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

I have also tried

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

and

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

What is the proper way to update original object defined by property ?

like image 342
Tariq Avatar asked Nov 06 '12 18:11

Tariq


3 Answers

After maddy's answer - this is from 2012 WWDC lecture on GCD and asynchronous programming:

__weak MyClass *weakSelf = self;

[tapBlockView setTapBlock:^(UIImage* image) {
    __strong MyClass *strongSelf = weakSelf;
    if(strongSelf) {
        [strongSelf.myImageArray addObject:image];
    }
}];
like image 159
Kaan Dedeoglu Avatar answered Sep 21 '22 08:09

Kaan Dedeoglu


Try a combination of the 2nd and 3rd.

__weak id weakSelf = self;
[tapBlockView setTapBlock:^(UIImage* image) {
    [weakSelf.myImageArray addObject:image];
}
like image 45
rmaddy Avatar answered Sep 21 '22 08:09

rmaddy


In your case you only need to reference an array which is referenced by self, so:

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

Works fine provided that self.myImageArray does not return different array references at different times. There is no cycle: the current object references the array and the block, and in turn the block references the array.

If self.myImageArray does return different array references as different times then use a weak reference to self, your case 3.

like image 26
CRD Avatar answered Sep 24 '22 08:09

CRD