Reputation: 9923
The delegate.deviceToken
expression below sometimes throws a bad pointer dereference, apparently out of 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
...
}
...
}
The AppDelegate declares deviceToken
like so:
@property (nonatomic, assign) NSString* deviceToken; // #NotMyCode
Quoth the crash report:
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)
The call to -[AppDelegate initializeWebServices]
can come out of the AFNetworkReachabilityManager
code, as it does in this case, or out of my application:didRegisterForRemoteNotificationsWithDeviceToken
. My deviceToken
is indeed not initialized in AppDelegate
, and so with it's assign
semantics it seems clear that I am trying to dereference garbage. But how does the nil check cause a call to objc_retain
?
Clearly it's worth trying to initialize deviceToken
to nil
, or update its memory management semantics. Also noteworthy in the code are a few booleans, the intent of which seems to be the protection of calls to initializeWebServices
, and which may be managed poorly.
But I have no idea how to reproduce this bug.
Upvotes: 4
Views: 1359
Reputation: 122401
The property is mis-declared; it should use the strong
or copy
attribute instead of assign
:
@property (nonatomic, strong) NSString* deviceToken;
Using assign
means the object is not being retained correctly, hence the exception.
Upvotes: 4