Objective c 当同一块被多次执行时,块中的weakSelf和strongSelf会发生什么情况? 前言
根据“For _弱对象,当前指针对象被保留,然后在当前完整表达式的末尾被释放。”这对我来说表示,如果我这样做:Objective c 当同一块被多次执行时,块中的weakSelf和strongSelf会发生什么情况? 前言,objective-c,objective-c-blocks,Objective C,Objective C Blocks,根据“For _弱对象,当前指针对象被保留,然后在当前完整表达式的末尾被释放。”这对我来说表示,如果我这样做: __weak typeof(self) weakSelf = self; [self doSomethingInBackgroundWithBlock:^{ if (weakSelf) { [weakSelf doSomethingInBlock]; } }]; 注 如果您在下面引用@dasblinkenlight的答案,您会注意到在doSomethi
__weak typeof(self) weakSelf = self;
[self doSomethingInBackgroundWithBlock:^{
if (weakSelf) {
[weakSelf doSomethingInBlock];
}
}];
注
如果您在下面引用@dasblinkenlight的答案,您会注意到在doSomethingBlock
之前有可能weakSelf
变成nil
假设doSomethingBlock
确实以存在的weakSelf
开始,那么它的其余部分应该不会出现问题,并且在完成执行之前不会有weakSelf
变为nil
的风险。但是,如果我要运行此命令:
__weak typeof(self) weakSelf = self;
[self doSomethingInBackgroundWithBlock:^{
if (weakSelf) {
// Guaranteed to be retained for scope of expression
[weakSelf doSomethingInBlock];
// weakSelf could possibly be nil before reaching this point
[weakSelf doSomethingElseInBlock];
}
}];
建议采用weakSelf
并将其转换为块内的强变量,如下所示:
__weak typeof(self) weakSelf = self;
[self doSomethingInBackgroundWithBlock:^{
__strong typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf doSomethingInBlock];
[strongSelf doSomethingElseInBlock];
}
}];
问题:
在同一块的多次迭代过程中,weakSelf
和strongSelf
会发生什么变化?在processBlock()
(以下)中,self是否可能存在于某些对象中,而不存在于其他对象中
例子
例如,如果我在后台使用类似的方法处理对象数组,其中processBlock
包含对self的引用:
- (void) processValuesInBackgroundWithArray:(NSArray *)array usingBlock:(void (^)(id))processBlock {
for (id ob in array) {
// Block is called for each Object
// Is there a chance that self will exist for some objects and not for others?
processBlock(ob);
}
}
这样称呼:
__weak typeof(self) weakSelf = self;
[self processValuesInBackgroundWithArray:someArray usingBlock:^(id object) {
__strong typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
[self doSomethingWithObject:object];
[self doSomethingElseWithObject:object];
}
}];
因此,块引用了
weakSelf
中的strongSelf
,但该块执行了多次。在数组中对象的迭代之间,strongSelf
是否有可能变成nil
无法保证在第一个示例中,if
中的weakSelf
将是非nil
,因为块有两个引用它的完整表达式:
检查是第一个完整表达式if(weakSelf)
[weakSelf doSomethingInBlock]中的
代码>调用是第二个weakSelf
weakSelf
调用受if
语句“保护”,也应该应用strongSelf
的技巧
在processBlock()中,self是否可能存在于某些对象中,而不存在于其他对象中
由于在processvaluesinbackgrounditharray:
调用中的过程值之前的堆栈帧中没有保证的\uu strong
引用,self
可能在循环的迭代之间被释放,但只有在调用最后一个代码段时,才会对\uu-weak
或对包含上一个代码段中的方法的对象的未恢复引用进行调用
假设您的最后一个代码片段位于名为testWeak
的方法中,位于名为MyClass
的类中:
-(void)testWeak {
__weak typeof(self) weakSelf = self;
[self processValuesInBackgroundWithArray:someArray usingBlock:^(id object) {
__strong typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
[self doSomethingWithObject:object];
[self doSomethingElseWithObject:object];
}
}];
}
这样打电话的时候
[myClassObj testWeak];
而myClassObj
是\u strong
,通过对myClassObj
的强引用,内部的self
对象将保留在调用之外,因此无论是否使用strongSelf
技巧,您的代码都是好的
然而,当myClassObj
弱时,最后一个\uu strong
引用与正在运行的循环同时被释放,循环中的一些对象最终会在块中看到nil
。strongSelf
唯一的区别是防止doSomethingWithObject
在nil
上被调用,而doSomethingWithObject
在非nil
对象上被调用。谢谢您的回答!我在问题中添加了关于我的第一个街区的注释。我对最后一部分有点困惑,你有没有可能举一个简短的例子。否则,请给我一分钟时间重读并吸收它,以便我理解它。谢谢@Loganself
可能存在于块的一次迭代中,然后在该块迭代结束时被解除分配。例如,块中的强引用可能是保持其分配的最后一件事。在这种情况下,弱引用将在下一次迭代开始之前被置零。谢谢@Tommy,这对我来说很有意义!请注意,您不需要在目标C中的if中检查weakSelf-只需在weakSelf上调用方法是安全的。如果weakSelf为nil,则在对其调用方法时不会发生任何事情。这是ObjC的主要原则之一—几乎不需要检查nil。您的工作假设是,如果对象为nil,方法调用就不会执行。对于strongSelf,这是一个风格问题,但惯例是“if(!strongSelf)return;”,而不是将代码放入if块中。无论你想遵循哪一种:“限制化”的观点是在整个区块中保证自己是零或实际值,这比让弱引用在中间某个地方过期的选择要好得多。主要是想从一个执行到另一个执行,这应该会给你答案。自我的生命周期与你对这个对象所做的任何事情都有关系,而不是与这个块有关。它有可能在块中消失,但这只是因为您丢失了对父对象的所有强引用。