8

我在我的项目中遇到了一个问题,我在头文件中声明了一个 NSMutableDictionary 属性,如下所示:

@property (copy, nonatomic) NSMutableDictionary *DataDict ;

现在在实现文件中,我继续初始化这个字典,因为我要使用它,像这样:

DataDict = [[NSMutableDictionary alloc]init];

现在,当我这样做时,当我尝试向这本字典中添加一些内容时,我会收到以下错误消息:

-[__NSDictionaryI setObject:forKey:]:无法识别的选择器发送到实例 0x885ae60 2012-10-19 16:51:56.040 testing[2297:c07] * 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:'-[__NSDictionaryI setObject: forKey:]: 无法识别的选择器发送到实例 0x885ae60'

一段时间后,我的项目运行了一千次,我决定取消注释我的初始化行,就像这样

 //DataDict = [[NSMutableDictionary alloc]init];

这解决了问题。

我的问题是:为什么?

4

3 回答 3

15

问题在于您定义属性的方式。如果您将其更改为:

@property (strong, nonatomic) NSMutableDictionary *DataDict ;

而不是copy一切都应该没问题。

发生这种情况是因为您基本上说您希望通过生成的访问器获得对象的副本,它返回一个NSDictionary而不是(一个不可变的副本)。

您可以在此处找到有关objective-c 属性的更多信息。

顺便说一句:objective-c ivars 通常以小写字母开头(大写名称用于类),因此dataDict应该优先于DataDict.

于 2012-10-19T21:08:03.763 回答
2

这是因为该属性具有“复制”属性,因此 NSMutableDictionary 实例 alloc/init-ed 是使用“复制”方法“复制”的,而“复制”方法创建的不是 NSMutableDictionary 而是 NSDictionary。(“mutableCopy”将创建 NSMutableDictionary)。

可能,您可以使用“保留”而不是“复制”作为属性。

@property (retain, nonatomic) NSMutableDictionary *DataDict ;

或者,只是没有“复制”/“保留”,但使用 ARC。(自动引用计数)。

于 2012-10-19T21:07:12.330 回答
0

我有这个确切的问题。保留/复制/强/弱等没有组合可以解决问题。起作用的是创建一个临时的可变字典,将其加载,然后将我的原始字典设置为等于它。

 NSMutableDictionary * tempD = [[NSMutableDictionary alloc] init];

[tempD setObject: epsTapeCut forKey:LWPrintParameterKeyTapeCut];
[tempD setObject: epsCopies forKey:LWPrintParameterKeyCopies];
[tempD setObject: epsHalfCut forKey:LWPrintParameterKeyHalfCut];
[tempD setObject: epsPrintSpeed forKey:LWPrintParameterKeyPrintSpeed];
[tempD setObject: epsDensity forKey:LWPrintParameterKeyTapeWidth];

self.ePSprintSettings = tempD;

这失败了:

 [self.ePSprintSettings setObject: epsTapeCut forKey:LWPrintParameterKeyTapeCut];

宣言:

 @property (nonatomic, retain) NSMutableDictionary *ePSprintSettings;

(但同样,属性的组合不会产生影响。)

初始化:

 self.ePSprintSettings = (NSMutableDictionary *)[myUserDefaults dictionaryForKey:kEpsPrintSettings];

谢谢你帮助我理解。

我很高兴这有效,但我想了解原因。

于 2020-12-03T01:12:49.510 回答