iOS - EXC_BAD_ACCESS - 如何在ARC下实现?

时间:2015-09-01 10:19:11

标签: ios objective-c exc-bad-access

在我目前的项目中,我随机获取了exc_bad_access,但总是在同一行代码上(从方法返回NSNumber对象时)。

问题是,怎样甚至可能在ARC下发生exc_bad_access?

我没有使用任何unsafe_unretained指针或类似的东西。

这个帖子的第一个答案似乎解释了这些错误的一个可能原因,但不幸的是,我不太了解这个设置:

EXC_BAD_ACCESS using ARC and can't track on simulator

包含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:

Stacktrace

2 个答案:

答案 0 :(得分:0)

在Objective-C中,每个对象都可以为零。

由于您在尝试访问NSManagedObject上的属性时获得EXC_BAD_ACCESS,我会说您可能忘记在核心数据模型中检查该属性的“可选”。我猜你是将JSON从一些后端服务器转换为Core Data对象?也许所述属性的JSON值为null。

使用Core Data时,如果在未检查“optional”标志的变量中插入空值,则在访问变量时,如果为null,则可以获得EXC_BAD_ACCESS。

答案 1 :(得分:-2)

根据我的经验,当我调用一个不存在的方法或属性时会发生这种情况。换句话说,如果ImageVersion为nil,则它没有intValue。

您应该在代码中查看此内容。