__weak和块的强变量行为

时间:2015-07-07 10:46:14

标签: ios objective-c memory-management automatic-ref-counting objective-c-blocks

我是块的新手,在通过互联网阅读时,我发现必须使用弱变量来阻止,因为块保留了变量。与块一起使用self时我有点困惑。让我们举个例子:

@interface ViewController : UIViewController

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

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

这里我有一个ViewController,它已经使用copy属性声明了block属性。我不想做一个保留周期所以我知道在块中使用self我需要创建自我的弱对象,例如:

__weak typeof(self) weakSelf = self;

我想确定我的块在后台线程上执行,并且可能是用户在完成之前回击。我的块正在执行一些有价值的任务,我不希望它松动。所以我需要自我直到阻止结束。我在我的实现文件中执行了以下操作:

-(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);
}

根据我的说法,使用typeof(weakSelf) strongSelf = weakSelf;应该创建我的self的强引用,当用户回击时,self将在块内有一个强引用,直到范围结束。

请帮助我理解为什么会崩溃?为什么我的strongSelf没有抓住这个对象。

2 个答案:

答案 0 :(得分:3)

您的参考不强。只需添加Distinct指令,如下所示:

__strong

答案 1 :(得分:2)

我找到了答案。我自己很好奇,因为你的代码对我来说似乎是合法的。至少这个想法。所以我已经建立了一个类似的项目并进行了一些实验。问题是这一行:

typeof(weakSelf) strongSelf = weakSelf; 

将其更改为

__strong typeof(weakSelf) strongSelf = weakSelf;

根据@LDNZh或

的建议
typeof(self) strongSelf = weakSelf;

您的代码将有效。

更新:由于这个问题出现了很多,我对我的示例项目进行了一些更改。我将github提供给所有人,供将来参考。