@property 保留或复制
首先我读了这篇文章
我认为我应该在我的程序中使用“复制”。 问题是使用 NSMutableDictionary 副本它会终止。
***** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“-[__NSCFDictionary removeAllObjects]:发送到不可变对象的变异方法”**
我不知道“发送到不可变对象的变异方法”。 我没有将 NSDictionary 设置为 NSMutabledictionary 指针。
这是我的代码
.h文件
@interface Button : NSObject {
@private
NSString* gID;
NSString* gBackColor;
NSString* gIconImage;
int gIndex;
BOOL gEnable;
BOOL gVisible;
NSString* gText;
NSMutableDictionary* gEvents;
BOOL gUseCircle;
}
@property (nonatomic,copy) NSString *ID;
@property (nonatomic,copy) NSString *BackColor;
@property (nonatomic,copy) NSString *IconImage;
@property int Index;
@property BOOL Enable;
@property BOOL Visible;
@property (nonatomic,copy) NSString *Text;
@property (nonatomic,getter=getEvents,retain) NSMutableDictionary *Events;
@property BOOL UseCircle;
@end
.m文件
@implementation Button
@synthesize ID = gID;
@synthesize BackColor = gBackColor;
@synthesize IconImage = gIconImage;
@synthesize Index = gIndex;
@synthesize Enable = gEnable;
@synthesize Visible = gVisible;
@synthesize Text = gText;
@synthesize Events = gEvents;
@synthesize UseCircle = gUseCircle;
-(NSMutableDictionary*) getEvents
{
if (!gEvents)
{
gEvents = [[NSMutableDictionary alloc] initWithCapacity:20];
}
return gEvents;
}
- (id) init
{
self = [super init];
if (self != nil)
{
gID = @"";
gBackColor = @"";
gIconImage = @"";
gIndex = 0;
gText = @"";
gUseCircle = NO;
}
return self;
}
- (void) dealloc
{
[gID release];
[gBackColor release];
[gIconImage release];
[gText release];
[gEvents removeAllObjects];
[gEvents release];
gEvents = nil;
[super dealloc];
}
并实现
tBtnXML.Events = [self SplitEvents:tNode];
SplitEvents功能:
-(NSMutableDictionary*) SplitEvents:(NSDictionary*)pEvents
{
NSMutableDictionary *tEvents = [[NSMutableDictionary alloc] initWithCapacity:5];
// code blabla
//.
//.
//.
[tEvents setObject:tEvent forKey:[NSNumber numberWithInt:tEventName]];
[tEvent release];
return [tEvents autorelease];
}
但是我将NSMutableDictionary* gEvents属性从copy更改为retain,它执行正常。
有人可以告诉我我的代码有什么问题吗?
如果我的代码与 dealloc 不正确,请告诉我。
谢谢您的认可。
是的,所以我修复了我的设置器:
-(void) setEvents:(NSMutableDictionary*) pEvents
{
NSMutableDictionary* tNewDict = [pEvents mutableCopy];
[gEvents removeAllObjects];
[gEvents release];
gEvents = tNewDict;
}
这项工作没有错误。
这对我有很大帮助。
但我不能投票>“<~
所以谢谢你巴伐利亚:)
First I read this article
I think I should use "copy" in my programe.
Problem is using NSMutableDictionary copy it will terminate.
***** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary removeAllObjects]: mutating method sent to immutable object'**
I have no idea about "mutating method sent to immutable object".
I didn't set NSDictionary to NSMutabledictionary pointer.
Here is my code
.h file
@interface Button : NSObject {
@private
NSString* gID;
NSString* gBackColor;
NSString* gIconImage;
int gIndex;
BOOL gEnable;
BOOL gVisible;
NSString* gText;
NSMutableDictionary* gEvents;
BOOL gUseCircle;
}
@property (nonatomic,copy) NSString *ID;
@property (nonatomic,copy) NSString *BackColor;
@property (nonatomic,copy) NSString *IconImage;
@property int Index;
@property BOOL Enable;
@property BOOL Visible;
@property (nonatomic,copy) NSString *Text;
@property (nonatomic,getter=getEvents,retain) NSMutableDictionary *Events;
@property BOOL UseCircle;
@end
.m file
@implementation Button
@synthesize ID = gID;
@synthesize BackColor = gBackColor;
@synthesize IconImage = gIconImage;
@synthesize Index = gIndex;
@synthesize Enable = gEnable;
@synthesize Visible = gVisible;
@synthesize Text = gText;
@synthesize Events = gEvents;
@synthesize UseCircle = gUseCircle;
-(NSMutableDictionary*) getEvents
{
if (!gEvents)
{
gEvents = [[NSMutableDictionary alloc] initWithCapacity:20];
}
return gEvents;
}
- (id) init
{
self = [super init];
if (self != nil)
{
gID = @"";
gBackColor = @"";
gIconImage = @"";
gIndex = 0;
gText = @"";
gUseCircle = NO;
}
return self;
}
- (void) dealloc
{
[gID release];
[gBackColor release];
[gIconImage release];
[gText release];
[gEvents removeAllObjects];
[gEvents release];
gEvents = nil;
[super dealloc];
}
And implement
tBtnXML.Events = [self SplitEvents:tNode];
SplitEvents function:
-(NSMutableDictionary*) SplitEvents:(NSDictionary*)pEvents
{
NSMutableDictionary *tEvents = [[NSMutableDictionary alloc] initWithCapacity:5];
// code blabla
//.
//.
//.
[tEvents setObject:tEvent forKey:[NSNumber numberWithInt:tEventName]];
[tEvent release];
return [tEvents autorelease];
}
But I chage NSMutableDictionary* gEvents property from copy to retain , it execute normal.
Colud anyone tell me what's wrong with my code?
If my code is incorrect with dealloc,please tell me.
Thank you appriciate.
Yes, So I fixed my setter:
-(void) setEvents:(NSMutableDictionary*) pEvents
{
NSMutableDictionary* tNewDict = [pEvents mutableCopy];
[gEvents removeAllObjects];
[gEvents release];
gEvents = tNewDict;
}
This work with no error.
It helps me a lot.
But I can't vote up >"<~
So thank you Bavarious :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
一般来说,可变属性应该是
retain
而不是copy
。当您将属性声明为copy
时,合成的 setter 方法会将-copy
发送到分配给该属性的对象。对于可变对象(例如NSMutableDictionary
),向它们发送-copy
会生成不可变副本,从而有效地创建不可变类型的对象(例如NSDictionary
)。因此:
合成的 setter 将
-copy
发送到[self SplitEvents:tNode]
,从而创建该字典的不可变副本(即,一个NSDictionary 实例),并将其分配给
gEvents
。这是错误的原因:gEvents
被声明为NSMutableDictionary
但指向NSDictionary
。根据记录,可变类通常声明一个
-mutableCopy
方法来创建可变副本。但它不被声明的属性使用。如果您不想使用retain
,则需要实现一个使用-mutableCopy
的自定义 setter。In general, mutable properties should be
retain
instead ofcopy
. When you declare a property as beingcopy
, the synthesised setter method sends-copy
to the object that’s being assigned to the property. In the case of mutable objects (e.g.NSMutableDictionary
), sending-copy
to them makes an immutable copy, effectively creating an object of immutable type (e.g.NSDictionary
) instead.So in:
the synthesised setter sends
-copy
to[self SplitEvents:tNode]
, thus creating an immutable copy of that dictionary (i.e., anNSDictionary
instance), and assign it togEvents
. This is the cause of your error:gEvents
is declared asNSMutableDictionary
but points to anNSDictionary
instead.For the record, mutable classes usually declare a
-mutableCopy
method that does make a mutable copy. It is not used by declared properties, though. If you do not want to useretain
, you need to implement a custom setter that uses-mutableCopy
.