NSManagedObjectContext executeFetchRequest返回不稳定的对象,导致EXC_BAD_ACCESS,SIGABRT等

我的猜测是我在这里错过了一些核心数据的基本理解,但在这里:

我在我的应用程序中有几个提取请求来处理不同事情的检索。 在某些情况下,代码运行正常,返回请求的对象。

在某些情况下,它会返回看起来已经被释放的对象(例如,稍后尝试引用返回的结果给出EXC_BAD_ACCESS)的几行代码。 当我在代码中设置各种断点和日志语句并逐步完成时,还会在代码中的其他位置获得偶然的SIGABRT或EXC_BAD_ACCESS。

在任何情况下,似乎是在我参考提取请求的结果时。

下面是一个这样的获取请求的示例:

// Who am I? NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSString *signedInPersonId = [defaults stringForKey:@"signedInPersonId"]; // Return (if any) the Request object with given UUID RequestStrings *r = [[RequestStrings alloc] init]; NSEntityDescription *description = [NSEntityDescription entityForName:r.table_Request inManagedObjectContext:moc]; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(UUID == %@) && (dataOwnerId == %@)", UUID, signedInPersonId]; NSFetchRequest *request = [[NSFetchRequest alloc] init]; [request setEntity:description]; [request setPredicate:predicate]; NSError *error = nil; NSArray *requests = [moc executeFetchRequest:request error:&error]; Request *returnRequest = nil; if (requests != nil) { if ([requests count] > 0) { NSLog(@"getRequestWithId - requests array: %@, first: %@", requests, [requests objectAtIndex:0]); returnRequest = [requests objectAtIndex:0]; } else { returnRequest = nil; } } [r release]; [request release]; return returnRequest; 

PS这里有一些更多的信息在一些情况下,相同的代码将返回所需的对象,或抛出一个exception,说明[NSCFNumber length]是一个无法识别的select器。 不知道如何相同的实体描述+获取请求可以返回一个数组中的数组和另一个数字。

你基本上是这样做的:

 // (1) Create an array of stuff NSArray *myArray = [NSarray arrayWithObjects:a, b, c, nil]; // (2) Take the first one off id myObject = [myArray objectAtIndex:0]; // (3) Release everything [myArray release]; // (4) Return myObject return myObject; 

你只是使用CoreData来执行步骤(1)。

步骤(1)返回一个对象数组。 保留这些对象的唯一方法就是它们在*中的数组。 如果释放数组(步骤3),您将释放其中的所有对象。 为什么你期望myObject仍然存在步骤(4)?

尝试这个 :

 // Make sure that we keep a retain of returnRequest returnRequest = [[[requests objectAtIndex:0] retain] autorelease]; 

*对于那里的迂腐:我做了一个假设,使我的答案更简单。 在现实世界中,你不知道什么是保留你的对象 – 这取决于框架以及你的代码。 但是,保留任何您期望保留的内容是一个很好的做法。

你为什么不在退货之前的最后发行? 这应该解决你的问题,因为你创build它们之后立即发布。

@deanWombourne – 很好的build议,我认为你是对的。 事实certificate,我实际上是从一个僵尸崩溃(当我使用先前提取的托pipe对象的值时,在以前的视图控制器中没有使用自己的setter)。

解决scheme:EXC_BAD_ACCESS总是值得一下僵尸车道。 对内存pipe理进行尽职调查。