保存 ManagedObjectContext 时发生奇怪的崩溃
当我尝试保存模型时遇到奇怪的崩溃。这是我的代码:
TJModel *model = [TJModel sharedTJModel];
NSFetchRequest *request = [[[NSFetchRequest alloc] init]autorelease];
[request setReturnsObjectsAsFaults:NO];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"TJVideoList"inManagedObjectContext:[model managedObjectContext]];
[request setEntity:entity];
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[[model managedObjectContext] executeFetchRequest:request error:&error] mutableCopy];
if (error != nil)
NSLog(@"error %@",[error localizedDescription]);
TJVideoList *videoList = nil;
if ([mutableFetchResults count] == 0) {
videoList = (VideoList *)[NSEntityDescription insertNewObjectForEntityForName:@"TJVideoList"
inManagedObjectContext:[model managedObjectContext]];
}
else
{
videoList = [mutableFetchResults objectAtIndex:0];
}
[videoList addVideoListObject:recordedVideo];
error = nil;
if (![[model managedObjectContext] save:&error]) {
并且崩溃......这就是终端中所说的:
-[NSConcreteValue UTF8String]: unrecognized selector sent to instance 0x1d33f0
我认为这可能是释放对象的暗示,所以我像这样保留了它们:
[managedObjectContext setRetainsRegisteredObjects:YES];
没有运气。
I am getting a weird crash when I try to save my model. This is my code:
TJModel *model = [TJModel sharedTJModel];
NSFetchRequest *request = [[[NSFetchRequest alloc] init]autorelease];
[request setReturnsObjectsAsFaults:NO];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"TJVideoList"inManagedObjectContext:[model managedObjectContext]];
[request setEntity:entity];
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[[model managedObjectContext] executeFetchRequest:request error:&error] mutableCopy];
if (error != nil)
NSLog(@"error %@",[error localizedDescription]);
TJVideoList *videoList = nil;
if ([mutableFetchResults count] == 0) {
videoList = (VideoList *)[NSEntityDescription insertNewObjectForEntityForName:@"TJVideoList"
inManagedObjectContext:[model managedObjectContext]];
}
else
{
videoList = [mutableFetchResults objectAtIndex:0];
}
[videoList addVideoListObject:recordedVideo];
error = nil;
if (![[model managedObjectContext] save:&error]) {
And crash .....This is what said in the terminal:
-[NSConcreteValue UTF8String]: unrecognized selector sent to instance 0x1d33f0
I thought it might be a cuestion of deallocated objects, so I retained them like this:
[managedObjectContext setRetainsRegisteredObjects:YES];
With no luck.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的崩溃不是此代码的结果。
保存时的崩溃通常是由托管对象的属性错误引起的。在这种情况下,您在某处为字符串属性分配了错误的值。当上下文将字符串属性转换为 UTF8 字符串以进行持久化时,那里的对象(而不是 NSString)无法理解该消息并导致崩溃。
尽管此代码应该可以正常运行,但您确实有一些危险的做法:
这是一个不好的做法。
autorelease
与release相同。在完成处理之前,不应将其发送给对象。autorelease
将对象标记为在下次内存池耗尽时死亡。在某些情况下,这会意外地杀死该对象。虽然它不会在这里造成问题,但你不想养成走这条捷径的习惯,因为它最终会咬你一口。仅当当前范围已完成对象但对象被发送到范围之外(通常在方法返回中)时,才应使用 autorelease。
这里的可变数组和副本一样毫无意义。这显然出现在某个参考材料中,因为它在过去几个月中不断出现新手代码。如果您不打算更改数组,则没有理由让它可变。对于托管对象数组来说,复制该数组是没有意义的。
由于您没有用于获取的排序描述符,因此 mutableFetchResults 数组将采用随机顺序。如果返回多个对象(几乎总是这种情况),则每次运行代码时,您都会在零元素处获得一个随机
TJVideoList
对象。Your crash is not a result of this code.
Crashes in saves usually result from an error with an managedObject's attributes. In this case, you have somewhere assigned the wrong value to a string attribute. When the context goes to convert the string attribute to a UTF8 string for persistence, the object that is there instead of the NSString does not understand the message and the crash results.
Although this code should run okay, you do have some risky practices:
This is a bad practice.
autorelease
is the same as release. You should not send it to an object until you are complete done with it.autorelease
marks an object for death the next time the memory pool is drained. In some case, that will kill the object unexpectedly. While it won't cause problems here, you don't want to get into the habit of taking this short cut because it will eventually bite you.You should only use autorelease when the current scope is done with the object but the object is being sent outside the scope (usually in a method return.)
The mutable array here is pointless as is the copy. This is apparently in some reference material somewhere because it keeps cropping up novices code in the last few months. If you're not going to alter an array there is no reason to have it mutable. In the case of an array of managed objects, it is pointless to copy the array.
Since you have no sort descriptor for the fetch, the mutableFetchResults array will be in a random order. If you have more than one object returned, which is almost always the case, you will get a random
TJVideoList
object at the zero element every time you run the code.听起来更像是您在需要 NSString 的地方分配了一个 NSValue 实例(很可能是 NSNumber,因为它是最常用的子类)。 -retainsRegisteredObjects: 不太可能被需要(无论如何它都不会修复与内存相关的问题)。
这也可能是过度释放的问题。尝试在启用僵尸检测的情况下运行(请参阅“运行”菜单)。
Sounds more like you assigned an NSValue instance (NSNumber, most likely, as it is the most commonly used subclass) where an NSString was expected. The -retainsRegisteredObjects: is unlikely to be needed (it won't fix a memory related problem anyway).
It might possibly be an over-release issue, too. Try running with Zombie detection enabled (see the Run menu).