Objective c NSMutableDictionary内存管理

Objective c NSMutableDictionary内存管理,objective-c,Objective C,请通读下面的代码,并在最后一行解释为什么它会崩溃 NSMutableDictionary *dic1 = [[NSMutableDictionary alloc] initWithCapacity:10]; NSString *val = [[NSString alloc] initWithFormat:@"Deepak"]; NSString *key = [[NSString alloc] initWithFormat:@"First Name"]; int a = [val re

请通读下面的代码,并在最后一行解释为什么它会崩溃

NSMutableDictionary *dic1 = [[NSMutableDictionary alloc] initWithCapacity:10];
NSString *val = [[NSString alloc] initWithFormat:@"Deepak"];
NSString *key = [[NSString alloc] initWithFormat:@"First Name"];    

int a = [val retainCount];
a = [key retainCount];

[dic1 setObject:val forKey:key];
a = [val retainCount];
a = [key retainCount];

//self.mainDic = [dic1 copy];
self.mainDic = [dic1 mutableCopy];//mainDic is like @property(copy) NSMutableDictionary *
[self.mainDic setObject:@"Hi" forKey:@"Good"];//Problem

谢谢。

copy
属性不适用于可变类,因为它们不尊重可变性,只向实例发送
copy
消息-最后一行的内容基本上是:

// ... release previous mainDic, if any
mainDic = [[dic1 mutableCopy] copy];
由于
copy
消息会产生一个不可变的版本,
NSDictionary
,您可能会在调试时遇到无法识别的选择器
-setObject:forKey:
的异常


如果您想使用
copy
属性,您应该提供自己的setter,并删除该手册
mutableCopy
-例如,请参阅上的Apple文档。

copy
属性不适合可变类,因为它们不尊重可变性,只需将
copy
消息发送给实例-什么发生在最后一行的第二行基本上是:

// ... release previous mainDic, if any
mainDic = [[dic1 mutableCopy] copy];
由于
copy
消息会产生一个不可变的版本,
NSDictionary
,您可能会在调试时遇到无法识别的选择器
-setObject:forKey:
的异常


如果您想使用
copy
属性,您应该提供您自己的setter,并删除该手册
mutableCopy
——例如,请参阅上的苹果文档。

我几乎从未使用过除(非原子,保留)之外的修改器的属性 这帮我省去了很多麻烦, 然后在dealoc方法中将它们设置为零

我会这样做的

NSMutableDictionary *dic1 = [[NSMutableDictionary alloc] initWithCapacity:10];

NSString *val = [[NSString alloc] initWithFormat:@"Deepak"]; 
NSString *key = [[NSString alloc] initWithFormat:@"First Name"];    

[dic1 setObject:val forKey:key];

self.mainDic = dic1; //where mainDic is like @property (nonatomic, retain) NSMutableDictionary *

[self.mainDic setObject:@"Hi" forKey:@"Good"];

//let's clean this mess up 
[val release]; 
[key release]; 
[dic1 release];

除了(非原子,保留)之外,我几乎从未使用过带修饰符的属性 这帮我省去了很多麻烦, 然后在dealoc方法中将它们设置为零

我会这样做的

NSMutableDictionary *dic1 = [[NSMutableDictionary alloc] initWithCapacity:10];

NSString *val = [[NSString alloc] initWithFormat:@"Deepak"]; 
NSString *key = [[NSString alloc] initWithFormat:@"First Name"];    

[dic1 setObject:val forKey:key];

self.mainDic = dic1; //where mainDic is like @property (nonatomic, retain) NSMutableDictionary *

[self.mainDic setObject:@"Hi" forKey:@"Good"];

//let's clean this mess up 
[val release]; 
[key release]; 
[dic1 release];

@迪帕克!您的代码本身运行良好。除dic1的解引用和内存泄漏外,没有静态分析错误

self.mainDic=[dic1 mutableCopy];效果很好。请重新运行代码块。 我创建了一个新项目,将您的代码放入其中并进行了测试。没有问题


@Georg Fritzsche您的代码正在崩溃。

@Deepak!您的代码本身运行良好。除dic1的解引用和内存泄漏外,没有静态分析错误

self.mainDic=[dic1 mutableCopy];效果很好。请重新运行代码块。 我创建了一个新项目,将您的代码放入其中并进行了测试。没有问题


@Georg Fritzsche您的代码正在崩溃。

现在,如果所讨论的对象来自类的外部,并在以后从外部更改,从而破坏封装,该怎么办?例如,请参阅文档中的第一部分。我只是说我从未使用过copy,在这种情况下-在我的类中保留一个可以在外部更改的对象,我仍然希望保留过时的副本-我自己已经成功地创建了一个克隆方法,我来自C#,所以我不喜欢使用copy。建议不要在dealloc中使用属性。您应该释放inst vars,而不是将属性设置为nil。但是
copy
正是针对这些情况的,它清楚地传达了预期的行为。只有当可变类作为
copy
properties时,才需要一个自定义的setter。现在,如果所讨论的对象来自类的外部,并在以后从外部更改,从而破坏封装,该怎么办?例如,请参阅文档中的第一部分。我只是说我从未使用过copy,在这种情况下-在我的类中保留一个可以在外部更改的对象,我仍然希望保留过时的副本-我自己已经成功地创建了一个克隆方法,我来自C#,所以我不喜欢使用copy。建议不要在dealloc中使用属性。您应该释放inst vars,而不是将属性设置为nil。但是
copy
正是针对这些情况的,它清楚地传达了预期的行为。只有当可变类作为
copy
properties时,才需要自定义setter。什么代码?我只是说“在你的代码中会发生类似的事情”。@Georg Fritzsche当我运行@Deepak的代码时,在放置了你的以下代码之后,崩溃发生了。mainDic=[[dic1 mutableCopy]copy];我没说要用那个密码。。。这是
复制
属性的效果的一个例子。让我猜猜,您使用
mainDic
retain
assign
属性进行了测试?那样的话,你就不会有OP的问题了。什么代码?我只是说“在你的代码中会发生类似的事情”。@Georg Fritzsche当我运行@Deepak的代码时,在放置了你的以下代码之后,崩溃发生了。mainDic=[[dic1 mutableCopy]copy];我没说要用那个密码。。。这是
复制
属性的效果的一个例子。让我猜猜,您使用
mainDic
retain
assign
属性进行了测试?那样的话,你就不会有OP的问题了。