The following will perform a crash when setting CLBeacon to nil
.
CLBeacon *beacon = [[CLBeacon alloc] init];
beacon = nil; // crash
Is it not possible to deallocate an initialized CLBeacon
?
This can be reproduced by simply adding the code above to a fresh project inside the App Delegate's didFinishLaunchingWithOptions
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
CLBeacon *beacon = [[CLBeacon alloc] init];
beacon = nil; // crash
return YES;
}
The apple documentation for CLBeacon states:
The reason it crashes is an implementation detail that doesn't really matter, but it is due to the fact that
CLBeacon
s are not properly initialized when you just callinit
. When it deallocates,CLBeacon
dereferences it's_internal
ivar and crashes if it isNULL
.You can see this by looking at the value of the
CLBeacon->_internal
ivar in the debugger. If you create the beacon usinginit
then the ivar isNULL
, but if you create it with[[CLBeacon alloc] initWithCoder:nil]
it will have a value and it doesn't crash when you set the beacon tonil
.Ran into this problem while using a mocked subclass. My tests would crash every time a mocked subclass was dealloced by ARC.
Solution is to call the correct init method on CLBeacon. Looking here we see that there is an addition init method. Declare it in a category in your code.
Call this initializer if you need an instance of the class. Do not include in production code.