This happened few days before, our team got a Crashlytics error caused by a NSMangedObject returning a wrong data type.

Let’s call this NSManageObject FootPrint. We’ve had a property logID belonging to FootPrint for almost 3 years without any changes and it’s just a pure NSNumber with no custom setter or getter. This is what it looks like:

@interface FootPrint : NSMangedObject
@property (nonatomic, retain) NSNumber *logID;
@end

Everything has been working fine in these years but suddenly, BAM, it no long works. So what happened?

After testing on different iOS versions, we found out this issue only happened on iOS11. It led me to think that we used a name which is accidentally the same as of a private property newly added to NSManagedObject since iOS11. To prove this assumption, I printed out other NSManagedObject object’s logID to see if it exists.

(lldb) po [UserProfile logID]
UserProfile(0x95D1520)

(lldb) po [[UserProfile logID] class]
__NSCFString

As you can see, even UserProfile, which has no property or method called logID, prints out a __NSCFString object. It pretty much confirmed my assumption. But then to fulfill my own curiosity, I also tried other objects.

(lldb) po [self.title logID]
__NSCFString(0x23A300)

(lldb) po [self.datePicker logID]
AADatePicker(0x45CCC880)

(lldb) po [self.topLineView logID]
UIView(0x45DB1A40)

(lldb) po [self.cancelButton logID]
UIButton(0x45FB1470)

This result honestly surprised me. Seems like the private property logID is of NSObject but not NSManagedObject.

Conclusion:

  1. Avoid every chance of using logID as a property or method name.
  2. Pick a much more specific name or prepend a prefix to prevent further similar issues.