I have an Objective-C class, SBUSBDevice, which represents a USB drive that the user has plugged into their system. In one of my view controllers, I grab the dictionary containing these objects, add them to an array, and attempt to do things with this array:
#import "SBUSBSetupWindowController.h"
#import "SBAppDelegate.h"
#import "SBUSBDevice.h"
@interface SBUSBSetupWindowController ()
@property (strong) NSDictionary *usbDictionary;
@property (weak) IBOutlet NSTableView *tableView;
@property (weak) IBOutlet NSButton *enableStartupDiskButton;
@property (strong) NSMutableArray *usbArray;
@end
@implementation SBUSBSetupWindowController
- (id)initWithWindow:(NSWindow *)window {
self = [super initWithWindow:window];
if (self) {
// Initialization code here.
self.usbDictionary = [[(SBAppDelegate *)[NSApp delegate] usbDictionary] copy];
self.usbArray = [[NSMutableArray alloc] initWithCapacity:[self.usbDictionary count]];
[self.usbDictionary enumerateKeysAndObjectsUsingBlock:^(id key, SBUSBDevice *object, BOOL *stop) {
NSLog(@"%@ = %@", key, object);
[self.usbArray addObject:object]; // <-- CRASH OCCURS HERE
}];
}
return self;
}
Unfortunately, when I run the code, it throws the following exception:
[SBUSBDevice copyWithZone:]: unrecognized selector sent to instance 0x6080004602c0
As far as I know, I am not trying to copy any SBUSBDevice instances, so there should be not need to even execute copyWithZone:. I am using this same technique in other areas in my app, with slight differences, and they all work. Why is this exception being thrown?
Here is how the SBUSBDevice objects are originally created. Note that they are being put into the dictionary which is later referenced by the code above:
- (void)detectAndSetupUSBs {
if (!self.usbDictionary) {
self.usbDictionary = [[NSMutableDictionary alloc] initWithCapacity:10];
}
NSArray *volumes = [[NSFileManager defaultManager] mountedVolumeURLsIncludingResourceValuesForKeys:nil options:0];
BOOL isRemovable, isWritable, isUnmountable;
NSString *description, *volumeType;
BOOL acceptHFSDrives = [[NSUserDefaults standardUserDefaults] boolForKey:@"AcceptHFSDrives"];
for (NSURL *mountURL in volumes) {
NSString *usbDeviceMountPoint = [mountURL path];
if ([[NSWorkspace sharedWorkspace] getFileSystemInfoForPath:usbDeviceMountPoint isRemovable:&isRemovable isWritable:&isWritable isUnmountable:&isUnmountable description:&description type:&volumeType]) {
if (isRemovable && isWritable && isUnmountable) {
NSLog(@"Detected eligible volume at %@. Type: %@", usbDeviceMountPoint, volumeType);
if ([usbDeviceMountPoint isEqualToString:@"/"]) {
// Don't include the root partition in the list of USBs.
continue;
}
else {
if ([volumeType isEqualToString:@"msdos"] ||
([volumeType isEqualToString:@"hfs"] && acceptHFSDrives)) {
SBUSBDevice *usbDevice = [[SBUSBDevice alloc] init];
usbDevice.path = usbDeviceMountPoint;
usbDevice.name = [usbDeviceMountPoint lastPathComponent];
[SBAppDelegate uuidForDeviceName:usbDeviceMountPoint];
self.usbDictionary[usbDevice.name] = usbDevice;
}
}
}
}
}
}
And here's the text of the exception (it occurs once for every USB drive that is plugged in):
2014-09-17 15:59:50.586 Mac Linux USB Loader[875:303] -[SBUSBDevice copyWithZone:]: unrecognized selector sent to instance 0x608000469140
2014-09-17 15:59:50.596 Mac Linux USB Loader[875:303] (
0 CoreFoundation 0x00007fff8de8725c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff85e2ae75 objc_exception_throw + 43
2 CoreFoundation 0x00007fff8de8a12d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x00007fff8dde5272 ___forwarding___ + 1010
4 CoreFoundation 0x00007fff8dde4df8 _CF_forwarding_prep_0 + 120
5 AppKit 0x00007fff8aa79186 -[NSCell _setContents:] + 74
6 AppKit 0x00007fff8aa95f5c -[NSCell setObjectValue:] + 317
7 AppKit 0x00007fff8aa95c8e -[NSTextFieldCell setObjectValue:] + 91
8 AppKit 0x00007fff8ad13df6 -[NSTableView preparedCellAtColumn:row:] + 589
9 AppKit 0x00007fff8ad13a5e -[NSTableView _drawContentsAtRow:column:withCellFrame:] + 44
10 AppKit 0x00007fff8ad13793 -[NSTableView drawRow:clipRect:] + 1629
11 AppKit 0x00007fff8ad12fed -[NSTableView drawRowIndexes:clipRect:] + 776
12 AppKit 0x00007fff8abdc331 -[NSTableView drawRect:] + 1484
13 AppKit 0x00007fff8abb7557 -[NSView(NSInternal) _recursive:displayRectIgnoringOpacity:inGraphicsContext:CGContext:topView:shouldChangeFontReferenceColor:] + 1082
14 AppKit 0x00007fff8abb700d __46-[NSView(NSLayerKitGlue) drawLayer:inContext:]_block_invoke + 186
15 AppKit 0x00007fff8abb6e03 -[NSView(NSLayerKitGlue) _drawViewBackingLayer:inContext:drawingHandler:] + 2297
16 AppKit 0x00007fff8abb64f8 -[NSView(NSLayerKitGlue) drawLayer:inContext:] + 108
17 QuartzCore 0x00007fff8cb46812 CABackingStoreUpdate_ + 2220
18 QuartzCore 0x00007fff8cb45f60 ___ZN2CA5Layer8display_Ev_block_invoke + 59
19 QuartzCore 0x00007fff8cb45f1c x_blame_allocations + 84
20 QuartzCore 0x00007fff8cb45a2b _ZN2CA5Layer8display_Ev + 1539
21 AppKit 0x00007fff8abb63c3 _NSBackingLayerDisplay + 235
22 AppKit 0x00007fff8ab8d74b -[_NSViewBackingLayer display] + 811
23 QuartzCore 0x00007fff8cb45162 _ZN2CA5Layer17display_if_neededEPNS_11TransactionE + 590
24 QuartzCore 0x00007fff8cb448b1 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 35
25 QuartzCore 0x00007fff8cb4433c _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 236
26 QuartzCore 0x00007fff8cb43fd6 _ZN2CA11Transaction6commitEv + 388
27 QuartzCore 0x00007fff8cb54761 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 71
28 CoreFoundation 0x00007fff8ddb7d67 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
29 CoreFoundation 0x00007fff8ddb7cd7 __CFRunLoopDoObservers + 391
30 CoreFoundation 0x00007fff8dda8e94 CFRunLoopRunSpecific + 340
31 HIToolbox 0x00007fff8b725a0d RunCurrentEventLoopInMode + 226
32 HIToolbox 0x00007fff8b7257b7 ReceiveNextEventCommon + 479
33 HIToolbox 0x00007fff8b7255bc _BlockUntilNextEventMatchingListInModeWithFilter + 65
34 AppKit 0x00007fff8aa5624e _DPSNextEvent + 1434
35 AppKit 0x00007fff8aa5589b -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 122
36 AppKit 0x00007fff8aa4999c -[NSApplication run] + 553
37 AppKit 0x00007fff8aa34783 NSApplicationMain + 940
38 Mac Linux USB Loader 0x000000010001c432 main + 34
39 libdyld.dylib 0x00007fff83b445fd start + 1
)
I've tried everything that I've thought of, however, I am largely self-taught at Objective-C and I am afraid that I may be missing something. If you need any additional source code, please feel free to ask.