[英]Objective-C copy an NSArray properly?
我的iPhone应用程序一直在崩溃,在过去的血腥周中我将它缩小到这一行:
NSArray *fetchResults = [managedObjectContext executeFetchRequest:request error:&error];
我从上面得到了正确的结果,但是应用程序在访问后崩溃了( EXC_BAD_ACCESS
)。 如何复制fetchResults
的内容以便我可以使用它?
我试过了
NSArray *retVal = [[NSArray alloc] initWithArray:fetchResults];
NSArray *retVal = [[NSArray alloc] initWithArray:[fetchResults copy]];
NSArray *retVal = [[NSArray alloc] initWithArray:[fetchResults retain]];
但唯一不会使应用程序崩溃的是
NSArray *retVal = [[NSArray alloc] initWithArray:nil];
有人可以帮帮我吗? 我想我需要上Obj-C内存管理课程。
编辑:这是一个更完整的崩溃代码示例:
NSArray *fetchResults = [managedObjectContext executeFetchRequest:request error:&error];
[request release];
NSMutableArray *retVal = [NSMutableArray arrayWithCapacity:0];
for(Job *job in fetchResults){
//NSLog(@"dev: %@",job.lastmod_device);
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
[job.jobkey copy], @"entitykey",
[NSNumber numberWithInt:[job.lastmod_device timeIntervalSince1970]], @"job_lastmod_device",
[NSNumber numberWithInt:[job.lastmod_server timeIntervalSince1970]], @"job_lastmod_server",
[NSNumber numberWithInt:[job.customer.lastmod_device timeIntervalSince1970]], @"customer_lastmod_device",
[NSNumber numberWithInt:[job.customer.lastmod_server timeIntervalSince1970]], @"customer_lastmod_server",
[NSNumber numberWithInt:[job.productionschedule_lastmod_device timeIntervalSince1970]], @"productionschedule_lastmod_device",
[NSNumber numberWithInt:[job.productionschedule_lastmod_server timeIntervalSince1970]], @"productionschedule_lastmod_server", nil];
//NSLog(@"dict: %@", dict);
[retVal addObject:dict];
}
return retVal;
以及调用此方法的代码:
NSArray *arr2 = [self retrieveJobs];
(就是这样;我甚至从不使用变量)
编辑2:即使只使用空的for循环迭代获取的结果,并且对fetchResults
对象不执行任何操作fetchResults
导致应用程序崩溃。 这怎么可能呢?
你在挣扎; 这些代码行......
NSArray *retVal = [[NSArray alloc] initWithArray:fetchResults];
NSArray *retVal = [[NSArray alloc] initWithArray:[fetchResults copy]];
NSArray *retVal = [[NSArray alloc] initWithArray:[fetchResults retain]];
后两者是简单的泄漏。 第一种是制作副本的方法,但retVal = [fetchResults copy];
是制作副本的更好方法。
但是,当然,你根本不需要副本 。 那不是问题。 你接着说, 唯一没有崩溃的是空结果集。
这表明两件事之一; 您的结果集已损坏(不太可能)或您正在错误地访问结果集(可能)。
“颠簸”是你提出了一个关于崩溃的问题,不包括崩溃的回溯或崩溃的位置。 添加这些,您可能会在短时间内得到答案。
(并且不要冒犯“捶打” - 我们都这样做。即使经过20多年的Objective-C,我仍然需要面对,退后一步,思考一切,以摆脱颠簸。)
NSArray *retVal = [fetchResults retain]
应该为你保留一切。 它没有复制,但我希望这不是你想要做的。 你的第一次尝试应该复制。 如果你不小心,它们都容易泄漏(你的第二个例子保证泄漏)。 你确定你没有在程序中做其他事情使这部分代码失败吗?
如果这是你想要的,这里有一些做真正副本的选项:
NSArray *retVal = [fetchResults copy];
NSArray *retVal = [[NSArray alloc] initWithArray:fetchResults];
这两个都将保留数组返回给您。
您确定获取请求是否返回数据? 根据文件:
符合请求所指定条件的对象数组,该请求是从接收方和与接收方持久存储协调器关联的持久存储中获取的。 如果发生错误,则返回nil。 如果没有对象符合request指定的条件,则返回一个空数组。
此外,你能显示访问阵列的代码吗? 它是否与您执行获取请求的方法相同?
NSArray *retVal = [[NSArray alloc] initWithArray:fetchResults];
NSArray *retVal = [[NSArray alloc] initWithArray:[fetchResults copy]];
NSArray *retVal = [[NSArray alloc] initWithArray:[fetchResults retain]];
你确定fetchResults包含结果吗? 因为“fetchResults”对象本身可能会释放并指向某个垃圾位置 。 这就是你崩溃的原因。 检查并通知fetchResults是否为有效对象。
要获得没有引用原件的真实副本,您需要执行DEEP副本。 一种方法是归档数组并将其解压缩回NSArray。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.