Проблемы управления записью iPhone SDK - EXC_BAD_ACCESS - PullRequest
0 голосов
/ 21 апреля 2009

Я давно смотрю на эту же проблему и буду очень признателен за любую помощь или предложения. Я уверен, что это что-то простое, но я не могу найти это. В моем делегате приложения я загружаю кучу вспомогательных объектов (созданный мной объект, который поддерживает NSCopying) со следующим кодом:

NSString     *path    = [[NSBundle mainBundle] pathForResource:@"Accessories" ofType:@"plist"];
NSDictionary *accDict = [[NSDictionary alloc] initWithContentsOfFile:path];

self.colors = (NSArray *) [accDict objectForKey:@"Colors"]; 
self.exteriorAccessories = [self loadAccessoriesForMode:EXTERIOR_MODE withDictionary:accDict];
self.interiorAccessories = [self loadAccessoriesForMode:INTERIOR_MODE withDictionary:accDict];
[accDict release];  

И вот определение метода, вызывающего его:

-(NSArray *)loadAccessoriesForMode:(NSString *)mode withDictionary:(NSDictionary *) dictionary
{
    NSMutableArray *tempValues = [[NSMutableArray alloc] init]; 
    for (NSDictionary *value in [dictionary objectForKey:mode])  
    {
        Accessory *accessory = [[Accessory alloc] initWithDictionary:value];
        [tempValues addObject:accessory];
        [accessory release];
    }

    NSArray *returnArray = [[NSArray alloc] initWithArray:tempValues copyItems:YES];
    [tempValues release];
    [returnArray autorelease];

    return returnArray; 
}

Когда я попадаю в релиз для accDict, я получаю исключение EXC_BAD_ACCESS. Если я вынимаю освобождение аксессуара внутри цикла, все в порядке - но я пропускаю объекты Аксессуара (что мне кажется очевидным - если я его инициирую и выделяю, это моя работа, чтобы освободить его).

Когда я прохожу через это в отладчике, я вижу, что методы init, copy и dealloc все запускаются на моем объекте Accessory, как и ожидалось. Я также могу опубликовать код для объекта Accessory, если вы думаете, что это поможет, но я думаю, что проблема где-то в этом коде.

Ответы [ 4 ]

3 голосов
/ 21 апреля 2009

Я думаю, что нашел причину, но я опубликую это здесь, чтобы другие могли извлечь выгоду. Это на самом деле не имеет ничего общего с кодом, который я разместил. Скорее проблема была внутри вспомогательного объекта. Я устанавливал вещи напрямую, а не вызывал получателей через себя.

Итак, это:

value = [dict objectForKey:@"myKey"];

Вместо этого:

self.value = [dict objectForKey:@"myKey"];

Почему-то это вызывало у меня плохие побочные эффекты на самом NSDictionary (я думал, что это не изменчиво, но, похоже, я что-то испортил). Единственный способ найти это - воспользоваться очень полезным советом , который я нашел в «Какао с любовью» .

Когда я использовал опцию Print Description в XCode, я смог увидеть, что NSDictionary каким-то образом содержал объекты AccessoryValue - один из моих пользовательских объектов, которых НЕ должно было быть, поскольку он был просто загружен из простого plist. Описание печати можно найти в XCode, наведя указатель мыши на объект, чтобы увидеть его детали (в то время как процесс приостановлен в отладчике) и щелкнув маленькие стрелки вверх / вниз рядом с треугольником, который раскрывается в детали объекта. Для словарей это выгрузит все их содержимое на консоль.

0 голосов
/ 03 октября 2009

Я боролся с проблемой Exc_Bad_Access в течение дня и наконец нашел ответ. Проблема заключалась в том, что, когда я пытаюсь получить доступ к одному из объектов, хранящихся в NSDictionary, первый раз был в порядке, но при втором доступе объект оказался нулевым, хотя число объектов в словаре остается тем же. Это странное поведение было связано с выпуском объекта дважды. Вот пример:

NSString * nstring = [[[NSString alloc] init] autorelease] [AnNSDictonaryInstance setObject: nstring forKey: 0];

... [выпуск строки];

Заметьте, что для nstring был установлен autorelease, а затем снова отпустить? Это не покажет проблему сразу, если вы попытаетесь прочитать объект словаря второй раз. Я надеюсь, что однажды команда разработчиков Apple сможет пометить это как нарушение при компиляции.

Надеюсь, этот пост кому-нибудь поможет.

Уэйн Кэмпбелл

0 голосов
/ 21 апреля 2009

Запустите Clang для вашего кода. Это находка. Звонит правила! Он выполнит статический анализ вашего кода и сообщит вам о том, что у вас может быть утечка. Отличный материал.

0 голосов
/ 21 апреля 2009

Пожалуйста, добавьте к этому префикс "Я ничего не знаю о цели C, но":

Мне кажется, что вам нужно освободить дополнительные элементы после того, как вы скопировали их в returnArray, или, возможно, не указали copyItems.

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