【问题标题】:iOS, NSMutableDictionaryiOS, NSMutableDictionary
【发布时间】:2012-10-19 20:55:34
【问题描述】:

我的项目中有一个问题,我在头文件中声明了一个 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];

这就解决了问题。

我的问题是:为什么?

【问题讨论】:

    标签: iphone objective-c ios nsmutabledictionary


    【解决方案1】:

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

    @property (strong, nonatomic) NSMutableDictionary *DataDict ;
    

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

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

    您可以在objective-c properties here 上找到更多信息。

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

    【讨论】:

    • 这是否意味着我应该使引用变强,然后分配 init?还是让它变得强大而无需分配初始化?
    • 通过将其设为strong,您只是说您想与该对象保持牢固的关系(拥有)(这基本上意味着您希望在所有者解除分配时将其解除分配)。您仍然必须像往常一样分配/初始化对象。
    【解决方案2】:

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

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

    @property (retain, nonatomic) NSMutableDictionary *DataDict ;
    

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

    【讨论】:

      【解决方案3】:

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

       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];
      

      感谢您帮助我理解。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多