I'm getting the following error, which causes a SIGABRT
:
2015-09-10 17:54:23.859 MyApp[1310:2027719] ERROR CRASH #(null) -[NSIndexPath rangeOfCharacterFromSet:]: unrecognized selector sent to instance 0xc000000000000016
2015-09-10 17:54:23.879 MyApp[1310:2027719] ERROR Stack Trace: (
0 CoreFoundation 0x0000000183840248 <redacted> + 160
1 libobjc.A.dylib 0x00000001952640e4 objc_exception_throw + 60
2 CoreFoundation 0x00000001838472f4 <redacted> + 0
3 CoreFoundation 0x00000001838440a8 <redacted> + 928
4 CoreFoundation 0x000000018374696c _CF_forwarding_prep_0 + 92
5 UIKit 0x0000000188632a44 <redacted> + 104
6 UIKit 0x00000001887a0ff0 <redacted> + 76
7 UIKit 0x00000001887a10b0 <redacted> + 56
8 UIKit 0x00000001887a1194 <redacted> + 36
9 QuartzCore 0x0000000187bf0820 <redacted> + 320
10 QuartzCore 0x0000000187bf06c4 <redacted> + 32
11 QuartzCore 0x0000000187befe58 <redacted> + 276
12 QuartzCore 0x0000000187befbd8 <redacted> + 528
13 QuartzCore 0x0000000187be9300 <redacted> + 80
14 CoreFoundation 0x00000001837f7ff0 <redacted> + 32
15 CoreFoundation 0x00000001837f4f7c <redacted> + 360
16 CoreFoundation 0x00000001837f535c <redacted> + 836
17 CoreFoundation 0x0000000183720f74 CFRunLoopRunSpecific + 396
18 GraphicsServices 0x000000018d0436fc GSEventRunModal + 168
19 UIKit 0x0000000188322d94 UIApplicationMain + 1488
20 MyApp 0x00000001000437b0 main + 68
21 libdyld.dylib 0x000000019590ea08 <redacted> + 4
which looks like iOS is trying to send a message to an NSString
selector, but the message was sent to an NSIndexPath
. Weird!
I've since found the problem; I'd set the value of the text in a UILabel
to be a pointer to an object in a CoreData object's NSNumber
column (0xc000000000000016
) instead of an NSString
. My fix was added .intValue
to the NSNumber
before passing it to my enumToString:
method.
typedef NS_ENUM(NSInteger, MyEnum)
{
MyEnum1 = 1,
MyEnum2,
MyEnum3
};
- (NSString*)enumToString:(MyEnum)enumValue
{
switch (enumValue) {
case MyEnum1:
return @"One";
case MyEnum2:
return @"Two";
case MyEnum3:
return @"Three";
}
}
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCell"];
// cdObject is a managed object in CoreData. Its enumValue column is an NSNumber.
cell.textLabel.text = [self enumToString:cdObject.enumValue];
return cell;
}
This just leaves the question: Why would this cause iOS to try to send a message to the non-existant selector -[NSIndexPath rangeOfCharacterFromSet:]
?
The crash occurred just after completing a -[UITableViewDataSource tableView:cellForRowAtIndexPath:]
Ok, so the cause is most likely not some threading gone wrong. Core Data turns the NSManagedObjects into faults at some point. This might be related. Also, NSNumbers are kind of special objects: the pointer is a tagged pointer, and this tagged pointer might contain the actual numeric value. This might also be related. In any case, a message was sent to a pointer, and that pointer no longer points to an object that recognizes that message. Read here about tagged pointers: https://www.mikeash.com/pyblog/friday-qa-2012-07-27-lets-build-tagged-pointers.html