@property retain OR copy [英] @property retain OR copy
问题描述
首先,我阅读了这篇文章
我想我应该在我的程序中使用复制。
*由于未捕获的异常NSInternalInconsistencyException而终止应用程序,原因是:' - [__ NSCFDictionary removeAllObjects]:发送到不可变对象的mutating方法我不知道mutating method sent to immutable object。
我没有将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启用;
@property BOOL可见;
@property(nonatomic,copy)NSString * Text;
@property(nonatomic,getter = getEvents,retain)NSMutableDictionary * Events;
@property BOOL UseCircle;
@end
>
.m文件
@implementation按钮
@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];
//代码blabla
//。
//。
//。
[tEvents setObject:tEvent forKey:[NSNumber numberWithInt:tEventName]];
[tEvent release];
return [tEvents autorelease];
}
但是我chage NSMutableDictionary * gEvents属性从复制到保留,它执行正常。
Colud任何人都告诉我我的代码有什么问题?
如果我的代码不正确的dealloc,请告诉我。
谢谢appriciate。
_c
是的,所以我修复了我的setter:
- (void)setEvents :(NSMutableDictionary *)pEvents
{
NSMutableDictionary * tNewDict = [pEvents mutableCopy];
[gEvents removeAllObjects];
[gEvents release];
gEvents = tNewDict;
}
这个工作没有错误。
它帮助了我很多。
vote up><〜
谢谢Bavarious :)
copy
。当你声明一个属性为 copy
时,合成的setter方法发送 -copy
在可变对象(例如 NSMutableDictionary
)的情况下,发送 -copy
给它们使一个不可变的副本,实际上创建了一个不可变类型的对象(例如 NSDictionary
)。 因此:
tBtnXML.Events = [self SplitEvents:tNode];
/ pre>
合成设置程序将
-copy
发送到[self SplitEvents:tNode] / code>,从而创建该字典的不可变拷贝(即
NSDictionary
实例),并将其分配给gEvents
。这是你的错误的原因:gEvents
被声明为NSMutableDictionary
但指向NSDictionary
对于记录,可变类通常声明一个
-mutableCopy
方法做可变的副本。但是,它不被声明的属性使用。如果你不想使用retain
,你需要实现一个使用-mutableCopy
的自定义setter。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 :)
解决方案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:
tBtnXML.Events = [self SplitEvents:tNode];
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
.这篇关于@property retain OR copy的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!