【问题标题】:@property retain OR copy@property 保留或复制
【发布时间】:2011-08-02 17:41:15
【问题描述】:

首先我读到了article

我认为我应该在我的程序中使用“复制”。 问题是使用 NSMutableDictionary 副本,它将终止。

***** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“-[__NSCFDictionary removeAllObjects]: 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 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;
}

这项工作没有错误。

这对我帮助很大。

但我不能投票>"

所以谢谢巴伐利亚 :)

【问题讨论】:

    标签: objective-c copy properties nsmutabledictionary retain


    【解决方案1】:

    一般来说,可变属性应该是retain,而不是copy。当您将属性声明为 copy 时,合成的 setter 方法将 -copy 发送到分配给该属性的对象。对于可变对象(例如NSMutableDictionary),向它们发送-copy 会使不可变副本,从而有效地创建不可变类型的对象(例如NSDictionary)。

    所以在:

    tBtnXML.Events = [self SplitEvents:tNode];
    

    综合设置器将-copy 发送到[self SplitEvents:tNode],从而创建该字典的不可变副本(即NSDictionary 实例),并将其分配给gEvents。这是您的错误的原因:gEvents 被声明为 NSMutableDictionary,但指向 NSDictionary

    为了记录,可变类通常声明一个-mutableCopy 方法,该方法确实会生成一个可变副本。但是,声明的属性不使用它。如果不想使用retain,则需要实现一个使用-mutableCopy的自定义setter。

    【讨论】:

    • @wei NSMutableDictionary 确实实现了-mutableCopy——事实上,它符合NSMutableCopying 协议。问题在于,在合成 Objective-C 声明的属性时,setter 方法使用-mutableCopy
    • 感谢您的回复 :) NSMutableDictionary 复制返回一个不可变对象是不是很奇怪?我想我理解我的错误。
    • 好的~~~我明白了~ >"
    猜你喜欢
    • 2010-10-09
    • 2011-06-09
    • 1970-01-01
    • 2017-03-26
    • 2012-03-30
    • 1970-01-01
    • 2011-10-30
    • 1970-01-01
    相关资源
    最近更新 更多