正如问题所描述的, block 中的wSelf会变得悬空吗?
1 void bindDefaultCallbacks {
2 __weak typeof(self) wSelf = self;
2 [sessionManager setDataTaskDidReceiveDataBlock:^(NSURLSession * _Nonnull session, NSURLSessionDataTask * _Nonnull dataTask, NSData * _Nonnull data) {
4 __strong typeof(self) sSelf = wSelf;
5 if (!sSelf) {
6 return;
7 }
8
9 // will wSelf here become dangling ?
10 APIRequest *apiRequest = [wSelf apiRequestForTask:dataTask];
11 NSURLResponse *response = dataTask.response;
12 apiRequest.urlResponse = response;
13 }];
14 }
崩溃信息:
Exception Codes: SEGV_ACCERR at 0x0000000000000010
Exception Type: SIGSEGV
0 XXX ___73-[XXXX bindDefaultCallbacks:withSessionManager:]_block_invoke.251 (in XXX) 420
1 XXX -[AFURLSessionManager URLSession:dataTask:didReceiveData:] (in XXX) (AFURLSessionManager.m:1156) 20
最佳答案
在第 10 行,您将不会有悬空指针。 ARC 将确保指针有效或为零(Chris 的引用文献解释了这一点)。然而,在第 10 行,指针可能为零。无法保证 sSelf
引用将在第 5 行之后继续,因为此后不再使用它。
也没有 promise wSelf
将在第 10 行为零。两种情况都是有效的。仅 promise 它是指向 self
的有效指针或 nil。
这条规则的正式定义来自Clang documentation discussion of Precise Lifetime Semantics (强调):
In general, ARC maintains an invariant that a retainable object pointer held in a
__strong
object will be retained for the full formal lifetime of the object. Objects subject to this invariant have precise lifetime semantics.By default, local variables of automatic storage duration do not have precise lifetime semantics. Such objects are simply strong references which hold values of retainable object pointer type, and these values are still fully subject to the optimizations on values under local control.
A local variable of retainable object owner type and automatic storage duration may be annotated with the
objc_precise_lifetime
attribute to indicate that it should be considered to be an object with precise lifetime semantics.
请参阅“对象活跃度”周围的部分以获取更多说明。
虽然这个特定的代码很难失败(在第 5 行和第 10 行之间的一个非常短暂的窗口期间,需要在不同的线程上释放该对象),但这种一般情况实际上是一个相当常见的原因错误。在调试版本中,强引用往往会一直存在,直到其范围结束,但在优化版本中,它们往往会尽快发布。因此,在开发过程中正常工作的代码在交付时可能会失败(如果您使用原始指针指向您认为正在保留的对象,甚至会崩溃)。
这个错误非常常见,以至于 UIKit 中有注释可以帮助防止它。如果您查看 UIColor.h,您会看到 CGColor
属性是这样定义的:
@property(nonatomic,readonly) CGColorRef CGColor;
- (CGColorRef)CGColor NS_RETURNS_INNER_POINTER CF_RETURNS_NOT_RETAINED;
NS_RETURNS_INNER_POINTER
是对 ARC 的警告,表明该指针应导致对象的生命周期延长,即使通常 ARC 不需要它。 (这是 early days of ARC 中崩溃的一个令人讨厌且常见的原因。)
关于objective-c - 当我在 OC 中使用强指针引用 block 中的弱指针时,它会变成悬空指针吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73051123/