Objective c 将对象添加到数组时程序崩溃

Objective c 将对象添加到数组时程序崩溃,objective-c,arrays,macos,cocoa,Objective C,Arrays,Macos,Cocoa,我有一个Objective-C类,SBUSBDevice,它表示用户已插入其系统的USB驱动器。在我的一个视图控制器中,我获取包含这些对象的字典,将它们添加到数组中,并尝试使用此数组执行操作: #import "SBUSBSetupWindowController.h" #import "SBAppDelegate.h" #import "SBUSBDevice.h" @interface SBUSBSetupWindowController () @property (strong) NS

我有一个Objective-C类,
SBUSBDevice
,它表示用户已插入其系统的USB驱动器。在我的一个视图控制器中,我获取包含这些对象的字典,将它们添加到数组中,并尝试使用此数组执行操作:

#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;
}
下面是异常的文本(每个插入的USB驱动器都会发生一次):


我已经尝试了我所想到的一切,然而,我在Objective-C上基本上是自学成才的,我担心我可能错过了一些东西。如果您需要任何其他源代码,请随时询问。

我想我知道发生了什么

您发送到usbDictionary的复制消息会将复制消息发送到它的每个内容(这对于几乎所有的集合项都是典型的)

因此,复制消息被发送到SBUSBDevice对象(存储在字典中),从而导致异常


看着随附的代码片段,我想不出我们在这里复制的原因。将对象添加到集合中会自动增加保留计数。

我相对确定这是一行:

self.usbDictionary = [[(SBAppDelegate *)[NSApp delegate] usbDictionary] copy];
如果您试图复制包含未实现复制协议的对象的字典,它将崩溃。你确定坠机发生在你认为发生的地方,而不是在这条线上吗


您正在引用cellForRowAtIndexPath中的usbArray来填充单元格,并将SBUSB设备指针直接粘贴到某个单元格显示结构中。可能您打算使用SBUSBDevice对象的某些属性(例如,NSString)。

如果查看异常堆栈跟踪,它将告诉您发生异常的位置。如果您向我们提供了异常堆栈跟踪(正如您所希望的),我们也会知道。@HotLicks我将尽快包括堆栈跟踪,但我现在无法测试程序。我将编辑问题并尽快将其包括在内。@HotLicks我已编辑问题以包括堆栈跟踪。很抱歉,延迟时间太长。您正在引用cellForRowAtIndexPath中的usbArray来填充单元格,并且将SBUSB设备指针直接插入单元格显示结构的某个位置。可能您想使用SBUSBDevice对象的某些属性(例如NSString)。@HotLicks就是这样,谢谢!:)请将其作为一个答案,以便我可以告诉您。即使没有
copy
语句,崩溃也会发生。我在收到错误后添加了它,因为我认为有一个单独的数据副本可能会解决问题。注释掉我指出的那行会导致错误消失,所以这行肯定是有问题的。问题是,没有它,问题就不起作用。即使没有
copy
语句,崩溃也会发生。我在收到错误后添加了它,因为我认为有一个单独的数据副本可以解决这个问题。没有副本,会出现什么异常?如果没有这一点,可能很难猜测。首先,我建议在块中使用弱引用。因此,添加一行
\uu弱blockSelf=self
,并在块内使用此blockSelf。如果没有副本,我会得到我刚才在问题中发布的异常。
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
)
self.usbDictionary = [[(SBAppDelegate *)[NSApp delegate] usbDictionary] copy];