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.
Вы должны проверить это в своем коде.