Objective-C EXC_BAD_ACCESS 分配对象 属性
Objective-C EXC_BAD_ACCESS with assign object property
下面的 delegate.deviceToken
表达式有时会抛出错误的指针取消引用,显然是出于 objc_retain()
.
MyWebServices.m:
@implementation MyWebServices
+ (void)initializeWithCompletionBlock:(void (^) (id data))completionBlock withErrorBlock:(void (^)(NSError* error))errorBlock {
AppDelegate* delegate = (AppDelegate*) [[UIApplication sharedApplication] delegate];
if (delegate.deviceToken == nil) { // MyWebServices.m:29
...
}
...
}
AppDelegate 声明 deviceToken
像这样:
@property (nonatomic, assign) NSString* deviceToken; // #NotMyCode
引用崩溃报告:
Code Type: ARM-64 (Native)
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000f434c4388
Triggered by Thread: 0
0 libobjc.A.dylib 0x0000000180a940b0 objc_retain + 16 (objc-object.h:341)
1 MyApp 0x0000000100054f98 +[MyWebServices initializeWithCompletionBlock:withErrorBlock:] + 200 (MyWebServices.m:29)
2 MyApp 0x000000010003b97c -[AppDelegate initializeWebServices] + 224 (AppDelegate.m:380)
3 MyApp 0x00000001000b123c __47-[AFNetworkReachabilityManager startMonitoring]_block_invoke + 132 (AFNetworkReachabilityManager.m:199)
对 -[AppDelegate initializeWebServices]
的调用可以来自 AFNetworkReachabilityManager
代码,就像在本例中一样,也可以来自我的 application:didRegisterForRemoteNotificationsWithDeviceToken
。我的 deviceToken
确实 不是 在 AppDelegate
中初始化的,因此根据它的 assign
语义,很明显我正在尝试取消引用垃圾。但是 nil 检查如何导致调用 objc_retain
?
显然值得尝试将 deviceToken
初始化为 nil
,或更新其内存管理语义。代码中还值得注意的是一些布尔值,其目的似乎是保护对 initializeWebServices
的调用,并且可能管理不善。
但我不知道如何重现这个错误。
属性 申报错误;它应该使用 strong
或 copy
属性而不是 assign
:
@property (nonatomic, strong) NSString* deviceToken;
使用assign
意味着对象没有被正确保留,因此出现异常。
下面的 delegate.deviceToken
表达式有时会抛出错误的指针取消引用,显然是出于 objc_retain()
.
MyWebServices.m:
@implementation MyWebServices
+ (void)initializeWithCompletionBlock:(void (^) (id data))completionBlock withErrorBlock:(void (^)(NSError* error))errorBlock {
AppDelegate* delegate = (AppDelegate*) [[UIApplication sharedApplication] delegate];
if (delegate.deviceToken == nil) { // MyWebServices.m:29
...
}
...
}
AppDelegate 声明 deviceToken
像这样:
@property (nonatomic, assign) NSString* deviceToken; // #NotMyCode
引用崩溃报告:
Code Type: ARM-64 (Native)
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000f434c4388
Triggered by Thread: 0
0 libobjc.A.dylib 0x0000000180a940b0 objc_retain + 16 (objc-object.h:341)
1 MyApp 0x0000000100054f98 +[MyWebServices initializeWithCompletionBlock:withErrorBlock:] + 200 (MyWebServices.m:29)
2 MyApp 0x000000010003b97c -[AppDelegate initializeWebServices] + 224 (AppDelegate.m:380)
3 MyApp 0x00000001000b123c __47-[AFNetworkReachabilityManager startMonitoring]_block_invoke + 132 (AFNetworkReachabilityManager.m:199)
对 -[AppDelegate initializeWebServices]
的调用可以来自 AFNetworkReachabilityManager
代码,就像在本例中一样,也可以来自我的 application:didRegisterForRemoteNotificationsWithDeviceToken
。我的 deviceToken
确实 不是 在 AppDelegate
中初始化的,因此根据它的 assign
语义,很明显我正在尝试取消引用垃圾。但是 nil 检查如何导致调用 objc_retain
?
显然值得尝试将 deviceToken
初始化为 nil
,或更新其内存管理语义。代码中还值得注意的是一些布尔值,其目的似乎是保护对 initializeWebServices
的调用,并且可能管理不善。
但我不知道如何重现这个错误。
属性 申报错误;它应该使用 strong
或 copy
属性而不是 assign
:
@property (nonatomic, strong) NSString* deviceToken;
使用assign
意味着对象没有被正确保留,因此出现异常。