ios - weakSelf (the good), strongSelf (the bad) and blocks (the ugly) -


i have read when block executed:

__weak typeof(self) weakself = self; [self dosomethinginbackgroundwithblock:^{         [weakself dosomethinginblock];         // weakself possibly nil before reaching point         [weakself dosomethingelseinblock]; }];  

it should done way:

__weak typeof(self) weakself = self; [self dosomethinginbackgroundwithblock:^{     __strong typeof(weakself) strongself = weakself;     if (strongself) {         [strongself dosomethinginblock];         [strongself dosomethingelseinblock];     } }]; 

so want replicate situation weakself gets nil in middle of block execution.

so have created following code:

* viewcontroller *

@interface viewcontroller ()  @property (strong, nonatomic) myblockcontainer* blockcontainer; @end  @implementation viewcontroller  - (ibaction)caseb:(id)sender {     self.blockcontainer = [[myblockcontainer alloc] init];     [self.blockcontainer createblockweakyfy];     [self performblock]; }   - (ibaction)casec:(id)sender {     self.blockcontainer = [[myblockcontainer alloc] init];     [self.blockcontainer createblockstrongify];     [self performblock]; }   - (void) performblock{     dispatch_async(dispatch_get_global_queue(dispatch_queue_priority_default, 0), ^{         self.blockcontainer.myblock();     });     [nsthread sleepfortimeinterval:1.0f];     self.blockcontainer = nil;     nslog(@"block container reference set nil"); } @end 

* myblockcontainer *

@interface myblockcontainer : nsobject  @property (strong) void(^myblock)();  - (void) createblockweakyfy; - (void) createblockstrongify;  @end  @implementation myblockcontainer  - (void) dealloc{     nslog(@"block container ey have been dealloc!"); }  - (void) createblockweakyfy{     __weak __typeof__(self) weakself = self;     [self setmyblock:^() {         [weakself sayhello];         [nsthread sleepfortimeinterval:5.0f];         [weakself saygoodbye];     }]; }  - (void) createblockstrongify{      __weak __typeof__(self) weakself = self;     [self setmyblock:^() {         __typeof__(self) strongself = weakself;         if ( strongself ){             [strongself sayhello];             [nsthread sleepfortimeinterval:5.0f];             [strongself saygoodbye];         }     }]; }  - (void) sayhello{     nslog(@"hello!!!"); }  - (void) saygoodbye{     nslog(@"bye!!!"); }   @end 

so expecting createblockweakyfy generate scenario wanted replicate haven't manage it.

the output same createblockweakyfy , createblockstrongify

hello!!! block container reference set nil  bye!!! block container ey have been dealloc! 

someone can tell me doing wrong?

your dispatch_async block creating strong reference. when block accesses myblockcontainer myblock property, creates strong reference life of block.

if change code this:

 __weak void (^block)() = self.blockcontainer.myblock;  dispatch_async(dispatch_get_global_queue(dispatch_queue_priority_default, 0), ^{     block(); }); 

you should see results expecting.


Comments

Popular posts from this blog

Fail to load namespace Spring Security http://www.springframework.org/security/tags -

sql - MySQL query optimization using coalesce -

unity3d - Unity local avoidance in user created world -