简体   繁体   English

__带有块的弱变量行为

[英]__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. 我是块的新手,在Internet上阅读时,我发现必须使用弱变量来块,因为块保留变量。 I am little confuse while using self with blocks. 将self与block一起使用时,我不会感到困惑。 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. 在这里,我有一个ViewController,它已声明具有copy属性的block属性。 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: 我不想进行保留循环,所以我知道在块中使用self时,我需要创建self的弱对象,例如:

__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; 根据我的说法,使用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. 应该为我的self创建一个强大的参考,当用户回击时,self仍然会在块内包含一个强大的参考,直到范围结束。

Please help me to understand why this get crash? 请帮助我了解为什么会崩溃? Why my strongSelf is not holding the object. 为什么我的strongSelf不持有该对象。

Your reference is not strong. 您的参考力不强。 Just add __strong directive like this: 只需添加__strong指令,如下所示:

__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 按照@LDNZh的建议或

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. 我将它在github上提供给所有人,以供将来参考。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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