@property сохранить или скопировать - PullRequest
3 голосов
/ 11 апреля 2011

Сначала я прочитал эту статью

Я думаю, что я должен использовать «копию» в моей программе.Проблема заключается в использовании копии NSMutableDictionary, которая будет прервана.

***** Завершение приложения из-за необработанного исключения «NSInternalInconsistencyException», причина: '- [__ NSCFDictionary removeAllObjects]: метод мутации отправлен в неизменный объект' **

Я понятия не имею о "мутирующем методе, отправленном в неизменяемый объект".Я не установил NSDictionary в NSMutabledictionary указатель.

Вот мой код

.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 файл

@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 из копии, чтобы сохранить, оно выполняется нормально.

Может кто-нибудь сказать мне, что не так с моим кодом?

Если мой код неверен сdealloc, скажите, пожалуйста.

Спасибо, ученик.

Да, поэтому я установил свой установщик:

-(void) setEvents:(NSMutableDictionary*) pEvents
{
    NSMutableDictionary* tNewDict = [pEvents mutableCopy];
    [gEvents removeAllObjects];
    [gEvents release];
    gEvents = tNewDict;
}

Эта работа без ошибок.

Это мне очень помогает.

Но я не могу проголосовать> "<~ </p>

Так что спасибоБаварский :)

1 Ответ

6 голосов
/ 11 апреля 2011

В общем случае изменяемые свойства должны быть retain вместо copy. Когда вы объявляете свойство как copy, метод синтезированного сеттера отправляет -copy объекту, который присваивается свойству. В случае изменяемых объектов (например, NSMutableDictionary), отправка -copy к ним делает неизменной копией , эффективно создавая объект неизменяемого типа (например, NSDictionary).

Итак, в:

tBtnXML.Events = [self SplitEvents:tNode];

синтезированный установщик отправляет -copy на [self SplitEvents:tNode], создавая тем самым неизменную копию этого словаря (т. Е. Экземпляр NSDictionary), и присваивает его gEvents. Это причина вашей ошибки: gEvents объявлен как NSMutableDictionary, но указывает вместо NSDictionary.

Для записи, изменяемые классы обычно объявляют метод -mutableCopy, который делает изменяемую копию. Однако он не используется объявленными свойствами. Если вы не хотите использовать retain, вам нужно реализовать пользовательский установщик, который использует -mutableCopy.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...