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
Post a Comment