iOS - EXC_BAD_ACCESS - Как это может происходить под ARC?

В моем текущем проекте я получаю exc_bad_access случайным образом, но всегда в одной и той же строке кода (при возврате объекта NSNumber из метода).

Вопрос в том, как вообще возможно, что exc_bad_access происходит под ARC?

Я не использую указатели unsafe_unretained или подобные вещи.

Первый ответ в этой теме, кажется, объясняет одну из возможных причин этих ошибок, но, к сожалению, я не совсем понимаю настройку:

EXC_BAD_ACCESS использует ARC и не может отслеживать на симуляторе

Интерфейс класса, в котором есть getImageVersion:

@interface PhotoFetcher : NSObject {

NSMutableData *photoData;
NSString *photoNick;

NSNumber *imageVersion; // <---- Strong ivar

PhotoSize photoSize;
}

Вот метод сбоя:

- (int)getImageVersion:(NSString *)nick
{
if (nick && !imageVersion)
{
    imageVersion = [[RuntimeData sharedData].nickImageVersionCache imageVersionForNick:nick];
    if (!imageVersion)
    {
        NSManagedObjectContext *context = [[RuntimeData sharedData].knuddelsDataStore managedObjectContext];

        [context performBlockAndWait:^{
            NSFetchRequest *userRequest = [NSFetchRequest fetchRequestWithEntityName:@"ConversationUser"];
            userRequest.predicate = [NSPredicate predicateWithFormat:@"nickname = [c] %@", nick];
            userRequest.propertiesToFetch = @[@"imageVersion"];
            userRequest.resultType = NSDictionaryResultType;
            userRequest.fetchLimit = 1;

            NSArray *objects = [context executeFetchRequest:userRequest error:nil];
            if (objects.count > 0)
            {
                NSDictionary *dict = objects[0];

                imageVersion = dict[@"imageVersion"];

                [[RuntimeData sharedData].nickImageVersionCache setImageVersion:imageVersion forNick:nick];
            }
        }];
    }
}
return imageVersion.intValue; // <<<<----- Line of Crash, exc_bad_access
} 

Это Stacktrace:

Трассировки стека

2 ответа

В Objective-C каждый объект может быть нулем.

Поскольку вы получаете EXC_BAD_ACCESS при попытке получить доступ к свойству в NSManagedObject, я бы сказал, что вы, возможно, забыли проверить "необязательный" в модели базовых данных для этого атрибута. Я полагаю, вы конвертируете JSON с какого-нибудь внутреннего сервера в объекты Core Data? Может быть, значение JSON для указанного атрибута равно нулю.

При использовании Core Data, если вы получаете нулевое значение, вставленное в переменную, для которой не установлен флажок "опционально", вы получите EXC_BAD_ACCESS при обращении к переменной, если она пуста.

По моему опыту, это происходит, когда я вызываю метод или свойство, которое не существует. Другими словами, если ImageVersion равен нулю, он не имеет intValue.

Вы должны проверить это в своем коде.

Другие вопросы по тегам