Objective c 将对象添加到数组时程序崩溃
我有一个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
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];