@property retain OR copy [英] @property retain OR copy

查看:252
本文介绍了@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 :)


retain 而不是 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 of copy. When you declare a property as being copy, 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., an NSDictionary instance), and assign it to gEvents. This is the cause of your error: gEvents is declared as NSMutableDictionary but points to an NSDictionary 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 use retain, you need to implement a custom setter that uses -mutableCopy.

这篇关于@property retain OR copy的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆