任何人都可以帮助解决 ARC 和内存相关的崩溃问题吗?
我有一个带有存储块指针的成员变量的类 LTRequest
:
typedef void (^APICallOKBlock)(id);
@interface LTRequest : NSObject
@property (nonatomic, strong) APICallOKBlock okCB;
@end
初始化该变量的代码:
-(void)addOKBlock:(APICallOKBlock)okBlock
{
self.okCB = okBlock;
}
如果成功,我调用块:
-(void)apiCallCompletedWithResult:(id)result
{
if(self.okCB != nil)
{
self.okCB(result);
}
}
作为引用,该块看起来像这样:
APICallOKBlock okBlock = ^(id result)
{
[self handleAPICallCompleted:result];
};
它调用在调度 api 调用的对象中定义的函数,但这部分并不重要。重要的是在 api 调用成功后调用
apiCallCompletedWithResult
时会发生什么。发生的情况是,当请求对象 LTRequest
被释放(SomeAppName 是我们的应用程序)时,块被调用,但应用程序很快崩溃:Thread 6 name: Dispatch queue: com.apple.root.low-priority
Thread 6 Crashed:
0 libobjc.A.dylib 0x300bad9c objc_release + 12
1 libobjc.A.dylib 0x300c6c00 objc_storeStrong + 24
2 SomeAppName 0x00055688 -[LTRequest .cxx_destruct] (LTRequest.m:12)
3 libobjc.A.dylib 0x300bba66 object_cxxDestructFromClass + 50
4 libobjc.A.dylib 0x300bba2c object_cxxDestruct + 8
5 libobjc.A.dylib 0x300b99ac objc_destructInstance + 20
我尝试使用
unsafe_unretained
而不是 strong
将块存储在 LTRequest
对象中:@property (nonatomic, unsafe_unretained) APICallOKBlock okCB;
在这种情况下,崩溃恰好与 if 一致:
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libobjc.A.dylib 0x300b9eda objc_retain + 10
1 libobjc.A.dylib 0x300c6bde objc_retainAutoreleasedReturnValue + 34
2 SomeAppName 0x00054f90 -[LTRequest apiCallCompletedWithResult:] (LTRequest.m:84)
3 SomeAppName 0x0002f8aa __29-[LTServerProxy makeAPICall:]_block_invoke_0 (LTServerProxy.m:154)
// file LTRequest.m
line 84 if(self.okCB != nil)
line 85 {
line 86 self.okCB(result);
line 87 }
我是否正确使用了指向块的指针,我应该如何调用它才不会导致任何崩溃?
一些信息:我使用的是 iOS SDK 5.0,部署目标是 4.0,设备 iPhone,并且整个项目都启用了 ARC。
最佳答案
您希望属性是 copy
而不是 retain
:
@property (nonatomic, copy) APICallOKBlock okCB;
关于ios - 使用块指针作为成员变量时,iOS 中与 ARC 相关的崩溃,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8852107/