Ios 防止滞留循环的两种堵塞方法

Ios 防止滞留循环的两种堵塞方法,ios,objective-c,block,retain-cycle,Ios,Objective C,Block,Retain Cycle,如果可能有一个保留周期,我通常会使用这样的块: - (void)someFunction { __weak __typeof(self) weakSelf = self; [self setHandler:^{ [weakSelf doSomething]; }]; } 但最近我看到了另一种方式,比如: - (void)someFunctionWithParam:(id)param { __weak __typeof(param) weakPar

如果可能有一个保留周期,我通常会使用这样的块:

- (void)someFunction {
    __weak __typeof(self) weakSelf = self;
    [self setHandler:^{
        [weakSelf doSomething];
    }];
}
但最近我看到了另一种方式,比如:

- (void)someFunctionWithParam:(id)param {
    __weak __typeof(param) weakParam = param;
    [self setHandler:^{
        __typeof(weakParam) strongParam = weakParam;
        [strongParam doSomething];
    }];
}    
他们之间有什么区别


Edit1:这是否意味着当运行处理程序时,
self
不会释放
param

在第二个示例中,在特定情况下创建
strongSelf
变量没有任何好处,但我可以向您展示一个有好处的示例

在第一个示例中,语句
[weakSelf doSomething]
weakSelf
中加载引用,保留它,发送
doSomething
消息,然后(在
doSomething
返回后)释放引用。第二个示例“手动”执行的步骤基本上完全相同

这里有一个稍微不同的例子:

- (void)someFunction {
    __weak __typeof(self) weakSelf = self;
    [self setHandler:^{
        [weakSelf doSomething];
        [weakSelf doAnotherThing];
    }];
}
在我的代码中,假设在调用块时只有一个对
self
对象的强引用。
[weakselfdosomething]
语句创建了对它的第二个临时强引用。当
doSomething
运行时,另一个线程释放另一个强引用。当
doSomething
返回时,语句将释放其临时强引用。现在,
self
不再具有强引用,因此它被解除分配,并且
weakSelf
被设置为nil

然后运行
[weakSelf doAnotherThing]
语句。它希望加载并保留
weakSelf
的内容,但由于
weakSelf
现在为nil,因此该语句只使用nil。它将
doAnotherThing
消息发送到nil,这是允许的,不会崩溃。它什么也不做。它不调用该方法

这可能不是您想要的行为。如果
doSomething
run,也许你总是想要
doothing
self
上运行。此时您需要第二个示例中的模式:

- (void)someFunctionWithParam:(id)param {
    __weak __typeof(self) weakSelf = self;
    [self setHandler:^{
        __typeof(weakSelf) strongSelf = weakSelf;
        [strongSelf doSomething];
        [strongSelf doAnotherThing];
    }];
}    

在这里,当调用块时,它立即在
strongSelf
中存储对
self
的强引用(或者如果
weakSelf
已设置为nil,则它存储nil)。在上次使用
strongSelf
变量之前,无法释放
strongSelf
引用,因此,
self
不可能在
doSomething
之后解除分配,但在
donotherthing
之前解除分配。很好的解释是,为什么它要引用两次?引用
weakSelf
的每个语句都独立运行,创建并随后释放对对象的强引用。这就是它的工作原理,和我想的一样。但是
self
没有问题,因为在运行
[self handler]
时,
self
不会是
nil
。但是
[self handler]
之前的
参数可能为零。如果需要获取
参数
,我们应该使用
[param copy]
来获取它的副本,对吗?那么为什么strongself doAnotherthing返回nil?如果do something正在创建和发布强引用,那么同样的事情也应该用于do other。