免责声明:我是一个完整的CoreData菜鸟。我在带有iOS 6.0.1的iPhone 4S上运行我的应用程序。
我的应用程序的一部分使用UIImagePicker
获取图像,并使用CoreData将它们保存到磁盘。所述图像与模型中的活动相关联。活动与图像有一对多的关系。
我需要在捕获后立即将图像保存到磁盘,然后将其故障排除内存,保留缩略图以供显示。如果不这样做,iOS会在捕获相对较少数量的图像后使用太多内存来杀死我的应用程序。
我将Thumbnails设为一个单独的实体,以避免在我需要的只是缩略图的情况下将整个图像带入内存。缩略图与图像具有一对一的关系。此外,由于各种原因,我没有使用核心数据来存储缩略图图像数据;相反,我存储文件名,并自己管理磁盘上的文件。
所有这些意味着,如果用户在添加了至少一个图像后取消添加活动,则需要删除用户添加的图像和缩略图。
当我尝试删除添加的图像对象时,会发生两件事。首先,Core Data抱怨我的删除规则:
Core Data: annotation: repairing missing delete propagation for to-one relationship image on object <Thumbnail: 0x1dd4d9e0> (entity: Thumbnail; id: 0x1dd4d410 <x-coredata:///Thumbnail/tE7E99D89-C986-4287-ABBD-C6BA7006E9264> ; data: {
activity = nil;
fileName = "ECD70C72-745A-4959-BF41-586E9521F1D6";
image = "0x1dd9f960 <x-coredata:///Image/tE7E99D89-C986-4287-ABBD-C6BA7006E9263>";
}) with bad fault 0x1dd9f960 <x-coredata:///Image/tE7E99D89-C986-4287-ABBD-C6BA7006E9263>
其次,当我尝试保存托管对象上下文时,保存失败,Core Data引发异常。这是NSError对象的输出:
Error Domain=NSCocoaErrorDomain Code=134030 "The operation couldn’t be completed. (Cocoa error 134030.)"
UserInfo=0x1f0ca270 {NSAffectedObjectsErrorKey=(
"<Image: 0x1dd9f910> (entity: Image; id: 0x1dd9f960 <x-coredata:///Image/tE7E99D89-C986-4287-ABBD-C6BA7006E9263> ;
data: {
activity = nil;
image = nil;
thumbnail = nil;
})"
), NSUnderlyingException=Cannot delete object that was never inserted.}
SO。显然我正在尝试删除一个我从未插入的对象?只有我很确定我做到了。
活动&lt; 1 - *&gt;图片;删除规则:级联
- &GT;反转:图像&lt; 1-1&gt;活动;删除规则:nullify
图像&lt; 1-1&gt;缩略图;删除规则:级联
- &GT;反转:缩略图&lt; 1-1&gt;图片;删除规则:nullify
图像采集:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage* acquiredImage = (UIImage*)info[UIImagePickerControllerEditedImage];
if (!acquiredImage) {
acquiredImage = (UIImage*)info[UIImagePickerControllerOriginalImage];
}
// Save the image to disk so we can fault it and free up its memory
NSManagedObjectContext* moc = [(ATAppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext];
Image* imageToSave = [NSEntityDescription insertNewObjectForEntityForName:@"Image" inManagedObjectContext:moc];
Thumbnail* thumbToSave = [NSEntityDescription insertNewObjectForEntityForName:@"Thumbnail" inManagedObjectContext:moc];
[addedImageManagedObjects addObject:imageToSave];
[addedThumbnailManagedObjects addObject:thumbToSave];
[thumbToSave setThumbnailImage:acquiredImage];
imageToSave.thumbnail = thumbToSave;
NSError* error;
[moc save:&error];
// TODO: error handling
// I know it doesn't look it, but this call will turn the imageToSave into a fault, thus freeing up its memory
[moc refreshObject:imageToSave mergeChanges:NO];
// NOW, we can add the thumbnail image to our collection view
// NOTE, -thumbnailImage is a method on my Thumbnail NSManagedObject subclass
[self addImage:[thumbToSave thumbnailImage] toCollectionView:imageDisplayView];
[self dismissModalViewControllerAnimated:YES];
}
取消处理程序:
- (IBAction)cancel:(id)sender {
NSManagedObjectContext* moc = [(ATAppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext];
// Delete any images we saved to disk
// Note that the activity object's changes get discarded b/c they were made on the child managed object context
// (We couldn't do that for images b/c we needed them to be written to disk and then faulted out of memory)
for (Thumbnail* thumb in addedThumbnailManagedObjects) {
// This method deletes the thumbnail image file whose storage I am managing myself
[thumb deleteThumbnailFile];
// I shouldn't have to explicitly delete the thumbnail since the delete of its image should cascade down...right?
}
for (Image* image in addedImageManagedObjects) {
[moc deleteObject:image];
}
NSError* error;
if (![moc save:&error]) {
NSLog(@"%@", error);
}
// TODO: error handling
[self resetToPristineState];
[self.presentingViewController dismissModalViewControllerAnimated:YES];
}
我无法看到我出错的地方,而且我收到的错误消息没有帮助。更糟糕的是,谷歌搜索错误消息并没有给我任何有用的结果。因此,我向你们提供了很有经验的人帮忙。
答案 0 :(得分:0)
喔。天啊。这个错误太愚蠢了。我很惭愧。
好。请注意,在我的图像采集处理程序中,我从未设置图像管理对象的图像数据?是啊。事实证明你需要这样做。 :)
无论如何,我已经解决了自己的问题。