简体   繁体   中英

__weak and strong variable behaviour with blocks

I am new to blocks and while reading over the internet I found that I must use weak variables to blocks, because blocks retains the variables. I am little confuse while using self with blocks. lets have an example:

@interface ViewController : UIViewController

@property (copy, nonatomic) void (^cyclicSelf1)();

-(IBAction)refferingSelf:(id)sender;
-(void)doSomethingLarge;
@end

Here I have a ViewController and it has declared block property with copy attribute. I don't want to make a retain cycle so I know when using self in the block I need to create weak object of self eg:

__weak typeof(self) weakSelf = self;

What I want to make sure is my block executes on background thread and may be user hit back before it get finish. My block are performing some valuable task and I don't want that to loose. So I need self till the end of block. I did following in my implementation file:

-(IBAction)refferingSelf:(id)sender
{
    __weak typeof(self) weakSelf = self; // Weak reference of block

    self.cyclicSelf1 = ^{

        //Strong reference to weak self to keep it till the end of block
        typeof(weakSelf) strongSelf = weakSelf;    
        if(strongSelf){
            [strongSelf longRunningTask];//This takes about 8-10 seconds, Mean while I pop the view controller
        }
        [strongSelf executeSomeThingElse]; //strongSelf get nil here
    };
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), self.cyclicSelf1);
}

According to me, using typeof(weakSelf) strongSelf = weakSelf; should create a strong reference of my self and when user hit back, self will still have one strong reference inside block until the scope get over.

Please help me to understand why this get crash? Why my strongSelf is not holding the object.

Your reference is not strong. Just add __strong directive like this:

__strong typeof(weakSelf) strongSelf = weakSelf;

I've found an answer. I was really curious myself, because your code seemed legit to me. The idea at least. So I've set up a similar project and experimented a little. The problem is this line:

typeof(weakSelf) strongSelf = weakSelf; 

Change it to either

__strong typeof(weakSelf) strongSelf = weakSelf;

as suggested by @LDNZh or

typeof(self) strongSelf = weakSelf;

And your code will work.

UPDATE: Since this question shows up a lot I've made some changes to my example project. I'm making it available on github for everyone for future reference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM