我在 Core Data 中存储了一系列个人资料图片作为 Binary Data
(启用了 Allows External Storage 选项,所以不要指责我存储图片在核心数据 :)
每张图片都显示在 UITableViewCell
中。目前,当用户点击显示表格 View 时会有轻微的延迟,大概是因为它是从 Core Data 加载它们,这对性能有足够的影响,可以在主线程上加载它们时锁定 UI。
我想将图像加载到一个单独的后台线程,以便立即显示表格 View ,并在从 Core Data 加载图像时显示图像。
我试过解决方案 in this post在 -cellForRowAtIndexPath:
方法中使用以下代码:
// Create the cell
MyCell *cell = [tableView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) {
// Get a reference to the object for this cell (an array obtained from Core Data previously in the code)
MyObject *theObject = [self.objectArray objectAtIndex:indexPath.item];
// Load the photo from Core Data relationship (ProfilePhoto entity)
UIImage *profilePhoto = [UIImage imageWithData:theObject.profilePhoto.photo];
// Set the name
cell.nameLabel.text = theObject.name;
dispatch_sync(dispatch_get_main_queue(), ^(void) {
// Set the photo
cell.photoImageView.image = profilePhoto;
});
});
// Return the cell
return cell;
但是,应用程序崩溃并出现以下错误(对 TableView 中的每一行重复):
CoreData: error: exception during fetchRowForObjectID: statement is still active with userInfo of (null)
如能帮助理解和解决此问题,我们将不胜感激。
最佳答案
solution which Marcus Zarra provided给了我一个关于如何解决这个问题的想法,但我认为将我实现的代码发布给任何其他寻求解决方案的人是值得的。所以,这是我为 -cellForRowAtIndexPath:
方法编写的新代码:
// Create the cell
MyCell *cell = [tableView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
// Get a reference to the object for this cell
MyObject *theObject = [self.objectArray objectAtIndex:indexPath.item];
// Reset the image
cell.imageView.image = nil;
// Set the name
cell.nameLabel.text = theObject.name;
// Check if the object has a photo
if (theObject.profilePhoto != nil) {
// Create a new managed object context for the background thread
NSManagedObjectContext *backgroundContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
backgroundContext.parentContext = self.managedObjectContext;
// Perform the operations on the new context
[backgroundContext performBlockAndWait:^{
// Fetch the object
NSError *error;
ProfilePhoto *profilePhotoObject = (ProfilePhoto *)[backgroundContext existingObjectWithID:theObject.profilePhoto.objectID error:&error];
// Create the image
UIImage *thePhoto = [UIImage imageWithData:myObject.profilePhoto];
dispatch_async(dispatch_get_main_queue(), ^(void) {
// Set the photo
cell.imageView.image = thePhoto;
});
}];
}
return cell;
您还需要更改 App Delegate 文件中创建托管对象上下文的行:
_managedObjectContext = [[NSManagedObjectContext alloc] init];
到
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
否则 .parentContext
分配将不起作用。
希望这对遇到此问题的其他人有所帮助!
关于ios - 在后台线程上将核心数据图像加载到 UITableViewCell 时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21322605/