避免在block中循环引用(Retain Cycle in Block)

让我们长话短说。请参阅如下代码:

 1 - (IBAction)didTapUploadButton:(id)sender
 2 {
 3   NSString *clientID = @"YOUR_CLIENT_ID_HERE";
 4 
 5   NSString *title = [[self titleTextField] text];
 6   NSString *description = [[self descriptionTextField] text];
 7 
 8   [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
 9 
10   __weak MLViewController *weakSelf = self;
11 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
12     UIImage *image = [UIImage imageNamed:@"balloons.jpg"];
13     NSData *imageData = UIImageJPEGRepresentation(image, 1.0f);
14 
15 [MLIMGURUploader uploadPhoto:imageData 
16                        title:title 
17                  description:description 
18                imgurClientID:clientID completionBlock:^(NSString *result) {
19   dispatch_async(dispatch_get_main_queue(), ^{
20     [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
21     [[weakSelf linkTextView] setText:result];
22   });
23 } failureBlock:^(NSURLResponse *response, NSError *error, NSInteger status) {
24   dispatch_async(dispatch_get_main_queue(), ^{
25   [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
26   [[[UIAlertView alloc] initWithTitle:@"Upload Failed"
27                               message:[NSString stringWithFormat:@"%@ (Status code %d)", 
28                                                [error localizedDescription], status]
29                              delegate:nil
30                     cancelButtonTitle:nil
31                     otherButtonTitles:@"OK", nil] show];
32   });
33 }];
34 
35   });
36 }

这是一个上传IMAGE的方法,这一段里面我们可以看到代码:

__weak MLViewController *weakSelf = self;

并且这样使用了weakSelf

[[weakSelf linkTextView] setText:result];

所以我们有一个问题:为什么我们不直接的使用self, 而是用一个weak指针指向他.并且在block区间使用这个weak指针.

这就是我要说的。我们都知道,block的属性是copy、self的属性是retain。因此,如果我们使用self在block部分,我们将得到一个retain循环(互相retain)。他们的内存永远不会释放。出于这个原因,我们必须要按照上面的方法做。

原文地址:https://www.cnblogs.com/yingkong1987/p/3313528.html