I'm attempting to debug a crash on iOS that reproduces consistently on devices that support the A64 instruction set. Specifically iPads using the A7/A8X SoC's. The exact same code will also consistently not crash when run on any 32-bit iPad (and the same applies if I restrict the build to only 32-bit architectures and then run the 32-bit code on a 64-bit capable iPad).
The crash reports as an EXC_BAD_ACCESS
, and there's nothing particularly fancy about the code that triggers it:
if (object && [self respondsToSelector:addSelector]) {
objc_msgSend(self, addSelector, object); //EXC_BAD_ACCESS on A64 devices!
//[self performSelector:addSelector withObject:object]; //no crash
}
The offending line is objc_msgSend(self, addSelector, object);
. The first perplexing part is that if I replace this line with [self performSelector:addSelector withObject:object];
, everything works as it should (though it leaves me with an obnoxious "PerformSelector may cause a leak..." warning). Unless I've completely misinterpreted something, objc_msgSend
and performSelector:withObject:
should be essentially equivalent in this case.
So why does one crash (and only when using A64) while the other does not?
The next perplexing thing comes when trying to debug the crash when it occurs. Both self
and object
are NSManagedObject
instances, and I can observe in the debugger that they are both valid objects. However, the exception is invariably reported as:
-[NSManagedObjectContext entity]: unrecognized selector sent to instance 0x...
The call is shown as originating from CoreData
's internals, and I can't come up with any plausible explanation of how that could be happening, particularly as a side-effect of switching from a 32-bit to a 64-bit architecture/build.
Are there any ideas on what would cause this kind of issue? Or should I just go with that performSelector:withObject:
and be happy?