使用的是iOS 5的父母,子女託管對象上下文:
我已經安排順序我的管理對象上下文:
persistent store coordinator --->
Private Queue Managed Object Context (for saving to disk in background) ----->
Main Queue Managed Object Context (for UI) ----->
Misc. Private Managed Object Contexts (for temporary jobs like UIImagePNGRepresentation() for example)
該模型看起來像:
Image Entity -> title : string , image : relationship(ImageBlob) optional
ImageBlob Entity -> image : Binary Data, imageEntity : relationship(Image)
關係反向設置。
一旦用戶完成採摘的圖像:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
// get the main queue managed object context
NSManagedObjectContext* mainQueueManagedObjectContext = self.managedObjectContext;
// get the image
UIImage* image = [info objectForKey:UIImagePickerControllerOriginalImage];
// create an object, using the managed object context for the main queue
NSManagedObject *newImage = [NSEntityDescription insertNewObjectForEntityForName:@"Image" inManagedObjectContext:mainQueueManagedObjectContext];
// edit not expensive properties
[newImage setValue:[NSString stringWithFormat:@"new title %i", [self tableView:self.tableView numberOfRowsInSection:0]] forKey:@"title"];
// lets save the main context to get a permanant objectID
[self saveContextForManagedObjectContext:mainQueueManagedObjectContext];
// get the permenant objectID, Thread Safe..
NSManagedObjectID* imageObjectID = newImage.objectID;
// create a private queue concurrent managed object context
NSManagedObjectContext* privateQueueManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
// set the main queue as the parent
[privateQueueManagedObjectContext setParentContext:mainQueueManagedObjectContext];
// we have to use blocks here, as this managed object context will work in a private queue
[privateQueueManagedObjectContext performBlock:
^{
// get the png representation in background
NSData* data = UIImagePNGRepresentation(image);
// get the managed object using the thread safe objectID
NSManagedObject* imageObjectInPrivateQueue = [privateQueueManagedObjectContext objectWithID:imageObjectID];
// insert a new object for the ImageBlob entity
NSManagedObject *imageBlobInPrivateQueue = [NSEntityDescription insertNewObjectForEntityForName:@"ImageBlob" inManagedObjectContext:privateQueueManagedObjectContext];
// set our image data
[imageBlobInPrivateQueue setValue:data forKey:@"image"];
// set the relationship to the original record
[imageObjectInPrivateQueue setValue:imageBlobInPrivateQueue forKey:@"image"];
// save changes to private queue context to main queue context
[self saveContextForManagedObjectContext:privateQueueManagedObjectContext];
// since we are not in the main queue, we have to ask the main managed object context using performBlock
[mainQueueManagedObjectContext performBlock:
^{
// what time is it before launching save in main queue
NSDate* startDate = [NSDate date];
// launch save on main queue
[self saveContextForManagedObjectContext:mainQueueManagedObjectContext];
// what time is it after finishing save in main queue
NSDate* finishDate = [NSDate date];
// see how long UI blocked
NSLog(@"blocked UI for %f seconds", [finishDate timeIntervalSinceDate:startDate]);
}];
}];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
{
[self.popOverController dismissPopoverAnimated:YES];
}
else
{
[self dismissViewControllerAnimated:YES completion:nil];
}
}
,這是儲蓄是如何完成的:
-(void)saveContextForManagedObjectContext:(NSManagedObjectContext*)managedObjectContext
{
// Save the context.
NSError *error = nil;
if (![managedObjectContext save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
這樣就大大減少UI堵塞,在iPhone 4,選擇5百萬像素圖像將阻止用戶界面僅0.015秒。另一方面,加載圖像也會在明顯的時間阻止UI,因此您可能也會在後臺加載該圖像。
而不是使用計時器,在選取器被解散後顯示的視圖的viewDidAppear方法中執行此操作。 – Shizam 2010-05-17 18:04:21
從iOS 5開始,您可以使用 - (void)dismissViewControllerAnimated:(BOOL)標誌完成的完成塊:(void(^)(void))completion;歸檔相同。 – Klaas 2012-07-31 20:59:21
我最近爲此已經在使用'dispatch_async'。我應該更新我的答案。 – 2012-07-31 21:38:49