gpt4 book ai didi

objective-c - 当同一个 block 被多次执行时,一个 block 中的 weakSelf 和 strongSelf 会发生什么?

转载 作者:太空狗 更新时间:2023-10-30 03:38:10 25 4
gpt4 key购买 nike

前言

根据Clang docs , "对于 __weak 对象,当前指针被保留,然后在当前完整表达式结束时释放。"这对我来说表明如果我这样做:

__weak typeof(self) weakSelf = self;
[self doSomethingInBackgroundWithBlock:^{
if (weakSelf) {
[weakSelf doSomethingInBlock];
}
}];
笔记

如果您引用下面@dasblinkenlight 的回答,您会注意到 weakSelf 有可能在 doSomethingBlock 之前变为 nil

假设 doSomethingInBlock,确实以存在的 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 并将其转换为 block 内的强变量,如下所示:

__weak typeof(self) weakSelf = self;
[self doSomethingInBackgroundWithBlock:^{
__strong typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf doSomethingInBlock];
[strongSelf doSomethingElseInBlock];
}
}];

问题

在同一 block 的多次迭代中,weakSelfstrongSelf 会发生什么变化?在 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];
}
}];

因此该 block 从weakSelf 引用了strongSelf,但是该 block 被执行了多次。 strongSelf 是否有可能在数组中的对象迭代之间变为 nil

最佳答案

无法保证在您的第一个示例中 if 中的 weakSelf 将是非 nil,因为该 block 有两个完整的引用它的表达式:

  • if (weakSelf) 检查第一个完整表达式
  • [weakSelf doSomethingInBlock]; 中的 weakSelf 是第二次调用。

因此,即使只有一个 weakSelf 调用受 if 语句“保护”,您的 strongSelf 技巧也应该适用。

Is there a chance that in processBlock()(below), self could exist for some objects and not for others?

由于 processValuesInBackgroundWithArray: 调用之前的堆栈帧中没有保证 __strong 引用,self 可能会在循环迭代之间释放,但仅在上一个代码片段的调用发生在 __weak 或对包含上一个代码片段方法的对象的未保留引用上的情况下。

假设您的最后一个代码片段位于名为 MyClass 的类中名为 testWeak 的方法中:

-(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__strongtestWeak中的self对象将在strong的调用之外保留引用 myClassObj,因此无论是否使用 strongSelf 技巧,您的代码都会很好。

然而,当 myClassObj 很弱时,最后一个 __strong 引用与运行循环同时释放,循环中的一些对象最终会看到一个 nil weakSelf block 内。 strongSelf 唯一的区别是防止 doSomethingElseWithObjectnil 上被调用,而 doSomethingWithObject将在非 nil 对象上调用。

关于objective-c - 当同一个 block 被多次执行时,一个 block 中的 weakSelf 和 strongSelf 会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23743851/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com