Любая возможная причина isa переменная сбрасывается в ноль? - PullRequest
1 голос
/ 20 октября 2011

Приложение для моего iPhone продолжает получать ошибку BAD_EXC_ACCESS после запуска в течение некоторого времени, после мучительной отладки я обнаружил, что одна из моих статических переменных (точнее NSPredicate) была повреждена: она все еще указывала на исходный адрес, но ее переменная isa была сброшенав 0!

Это меня совершенно не удивляет, почему переменная isa была сброшена в 0 ?!Есть идеи?

Спасибо!

Обновление: опубликовать код.На самом деле код взят из ABContactHelper * от erica Я немного изменил его, чтобы использовать шаблоны предикатов, чтобы сделать запрос более эффективным, поэтому я добавил эту функцию:

+ (NSPredicate*) predicateforMatchingName:(NSString*) name {
        //templateForMatchingName is a static variable I declare elsewhere
        //static NSPredicate * templateForMatchingName =nil;
    if (templateForMatchingName == nil) {
        templateForMatchingName = [NSPredicate predicateWithFormat:@"firstname contains[cd] $NAME1 OR lastname contains[cd] $NAME2 OR nickname contains[cd] $NAME3 OR middlename contains[cd] $NAME4"];
    }

    NSDictionary *sub = [NSDictionary dictionaryWithObjectsAndKeys:
                         name,@"NAME1",
                         name,@"NAME2",
                         name,@"NAME3",
                         name,@"NAME4",
                         nil];

    NSPredicate *pred = [templateForMatchingName predicateWithSubstitutionVariables:sub];
    return pred;
} 

Я думал, что этот кодСовершенно "нормально", templateForMatchingName невозможно изменить после того, как он был создан.Но потом я обнаружил, что переменная isa была сброшена.Это не обязательно установлено в ноль.На этот раз я обнаружил, что он был сброшен на другое значение.И странная вещь в том, что он все еще указывал на исходную область.

Есть идеи?

Ответы [ 3 ]

3 голосов
/ 21 октября 2011

Вы вызываете метод класса, который возвращает автоматически освобожденный объект; попробуйте добавить вложенное сохранение во время создания экземпляра или просто используйте alloc & init.

И да, указатель будет указывать на исходный адрес, поэтому он генерирует это исключение. Если бы указатель был установлен в nil, он бы снова создал экземпляр вашего объекта из-за оператора if.

2 голосов
/ 20 октября 2011

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

0 голосов
/ 21 октября 2011

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

Кстати, для других, кто может быть заинтересован в проблеме, вы также можете обратиться к этому, Зачем сохранять статическую переменную?

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

...