在 IOS6 中使用 Core Data(删除/编辑)
Posted
技术标签:
【中文标题】在 IOS6 中使用 Core Data(删除/编辑)【英文标题】:Using Core Data in IOS6 (delete/edit) 【发布时间】:2013-03-01 15:18:24 【问题描述】:我正在将我的 tableviewdata 的最新 Internet 请求保存在(核心数据)实体中,但遇到有关“故障”的错误异常的问题。 我有两种方法“loadData”,它们获取将在我的表格视图中加载的最新“ordersitems”和“loadThumbnails”,它将尝试将缩略图缓存到核心数据实体中。 当托管对象被删除并且缩略图方法仍然尝试访问它时,就会出现问题。虽然我做了一个变量 stopThumbnails 来停止 loadThumbnails 方法,但问题一直在发生。
什么是延迟加载图像并将它们保存到 coredata 但检查对象是否未被删除的正确 ios 6 方法?我发现这个Core Data multi thread application 很有用,但我的新手对核心数据的理解仍然有限,而且我在编写代码时遇到了问题。我阅读了有关 http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/coredata/Articles/cdConcurrency.html 的苹果文档,但很难完全理解。
我至少希望我的 http 请求能够异步加载(但最好尽可能多地加载)我想出了以下内容:
-(void)viewdidload
NSFetchRequest *fetchReq = [NSFetchRequest fetchRequestWithEntityName:@"OrderItems"];
fetchReq.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]];
self.data = [self.managedObjectContext executeFetchRequest:fetchReq error:nil];
MYFILTER = @"filter=companyX";
[self loadData];
-(void)loadData
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
//json request from url
NSDictionary *reqData = myOrderJSONRequest(MYFILTER);
dispatch_async( dispatch_get_main_queue(), ^
if(reqData!=NULL && reqData!=nil)
//request successful so delete all items from entity before inserting new ones
stopThumbnails = YES;
for(int i=self.data.count-1;i>=0;i--)
[self.managedObjectContext deleteObject:[self.data objectAtIndex:i]];
[self.managedObjectContext save:nil];
if(reqData.count>0)
//insert latest updates
for (NSDictionary *row in reqData)
OrderItem *item = [NSEntityDescription insertNewObjectForEntityForName:@"OrderItem" inManagedObjectContext:self.managedObjectContext];
item.order_id = [NSNumber numberWithInt:[[row objectForKey:@"order_id"] intValue]];
item.description = [row objectForKey:@"description"];
item.thumbnail_url = [row objectForKey:@"thumbnail_url"];
[self.managedObjectContext save:nil];
NSFetchRequest *fetchReq = [NSFetchRequest fetchRequestWithEntityName:@"OrderItems"];
fetchReq.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]];
self.data = [self.managedObjectContext executeFetchRequest:fetchReq error:nil];
[TableView reloadData];
//LOAD THUMBNAILS ASYNCHRONOUS
stopThumbnails = NO;
[self loadThumbnails];
else
//NO INTERNET
);
);
-(void)loadThumbnails
if(!loadingThumbnails)
loadingThumbnails = YES;
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
for (int i=0;i<self.data.count; i++)
if(!stopThumbnails)
OrderItem *item = [self.data objectAtIndex:i];
if(item.thumbnail==NULL)
//ASYNCHRONOUS IMAGE REQUEST
NSURL *image_url = [NSURL URLWithString:item.thumbnail_url];
NSData *image_data = [NSData dataWithContentsOfURL:image_url];
dispatch_async( dispatch_get_main_queue(), ^
if(image_data!=nil && image_data!=NULL && !stopThumbnails)
//IMAGE REQUEST SUCCESSFUL
item.thumbnail = image_data;
[self.managedObjectContext save:nil];
//RELOAD AFFECTED TABLEVIEWCELL
NSIndexPath* rowToReload = [NSIndexPath indexPathForRow:i inSection:0];
NSArray* rowsToReload = [NSArray arrayWithObjects:rowToReload, nil];
[TableView reloadRowsAtIndexPaths:rowsToReload withRowAnimation:UITableViewRowAnimationFade];
else
loadingThumbnails = NO;
return;
);
if(stopThumbnails)
dispatch_async( dispatch_get_main_queue(), ^
loadingThumbnails = NO;
return;
);
else
dispatch_async( dispatch_get_main_queue(), ^
loadingThumbnails = NO;
return;
);
dispatch_async( dispatch_get_main_queue(), ^
loadingThumbnails = NO;
return;
);
);
任何帮助当然都非常感谢:)
【问题讨论】:
【参考方案1】:好吧,我不知道这是否是正确的方法,但它有效,所以我会将其标记为答案。
为了在后台执行所有操作,我使用了第二个 nsmanagedobjectcontext (MOC),然后将更改合并到主 MOC。尽管我必须使用 NSManagedObjectContextDidSaveNotification 来合并两个上下文的更改,但调度队列效果很好。
从 IOS 5 开始,可以使用块代替为您进行合并。所以我决定用这个而不是调度方式(这样我就不必使用通知了)。
当一个对象在后台队列中被选中而在另一个队列中被删除时,我也使用块时遇到了同样的问题(错误)。所以我决定不立即删除它,而是为 OrderItem 插入一个 NSDate 'deleted' 属性。然后有一个带有删除检查的计时器,以查看是否有超过 10 分钟前被删除的对象。这样我确信没有缩略图仍在下载。有用。虽然我仍然想知道这是正确的方法:)
【讨论】:
以上是关于在 IOS6 中使用 Core Data(删除/编辑)的主要内容,如果未能解决你的问题,请参考以下文章
iCloud Core Data iOS 6 到 iOS 7 最初是空的本地后备存储
了解如何将 UISearchBar 与 Core Data 一起使用
RestKit / Core Data:远程删除的实体不会从 Core Data 中删除