我正在使用AFNetworking从URL中提取图像,调整大小,存储到磁盘并在Core Data中记录路径,然后加载到表视图和存储。当代码执行时,它会冻结我的UI。我不确定这是导致我麻烦的下载还是操作。
我正在使用的代码位于
之下- (void)getPhoto:(NSInteger)type forManagedObject:(MyManagedObject*)object {
// download the photo
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:object.photoUrl]];
AFImageRequestOperation *operation = [AFImageRequestOperation imageRequestOperationWithRequest:request success:^(UIImage *image) {
// MyManagedObject has a custom setters (setPhoto:,setThumb:) that save the
// images to disk and store the file path in the database
object.photo = image;
object.thumb = [image imageByScalingAndCroppingForSize:CGSizeMake(PhotoBlockCellButtonWidth, PhotoBlockCellButtonHeight)];
NSError *nerror;
if (![[DataStore sharedDataStore].managedObjectContext save:&nerror]) {
NSLog(@"Whoops, couldn't save: %@", [nerror localizedDescription]);
return;
}
// notify the table view to reload the table
[[NSNotificationCenter defaultCenter] postNotificationName:@"ReloadTableView" object:nil];
}];
[operation start];
}
这是一个与我的托管对象
中的setter相关的示例代码- (NSString*)uniquePath{
// prepare the directory string
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
// acquire a list of all files within the directory and loop creating a unique file name
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *existingFiles = [fileManager contentsOfDirectoryAtPath:documentsDirectory error:nil];
NSString *uniquePath;
do {
CFUUIDRef newUniqueId = CFUUIDCreate(kCFAllocatorDefault);
CFStringRef newUniqueIdString = CFUUIDCreateString(kCFAllocatorDefault, newUniqueId);
uniquePath = [[documentsDirectory stringByAppendingPathComponent:(__bridge NSString *)newUniqueIdString] stringByAppendingPathExtension:@"png"];
CFRelease(newUniqueId);
CFRelease(newUniqueIdString);
} while ([existingFiles containsObject:uniquePath]);
return uniquePath;
}
- (NSString*)saveImage:(UIImage*)image{
NSString *path = [self uniquePath];
NSData *data = UIImagePNGRepresentation(image);
[data writeToFile:path atomically:YES];
return [NSString stringWithFormat:@"file://%@",path];
}
- (void) setPhoto:(UIImage *)image {
self.photoUrl = [self saveImage:image];
}
我想把它推到后台线程,但我不确定AFNetworking,Core Data和Messaging在线程安全方面的含义是什么。有什么想法吗?
答案 0 :(得分:4)
AFAIK,您执行请求的方式不正确:
[operation start];
您应该将操作添加到NSOperationQueue
:
NSOperationQueue* operationQueue = [[NSOperationQueue alloc] init];
[operationQueue addOperation:operation];
(你应该正确地对队列进行内存管理)。
通过这样做,您的请求将以异步方式执行,它不会阻止UI,您也不需要处理多线程。
答案 1 :(得分:3)
根据Matt的建议,我通过重新调整我的调用来改进UI。
- (void)getPhoto:(NSInteger)type forManagedObject:(MyManagedObject*)object {
// download the photo
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:object.photoUrl]];
AFImageRequestOperation *operation = [AFImageRequestOperation
imageRequestOperationWithRequest:request
imageProcessingBlock:^UIImage *(UIImage *image) {
return [image imageByScalingAndCroppingForSize:CGSizeMake(PhotoBlockCellButtonWidth, PhotoBlockCellButtonHeight)];
}
cacheName:nil
success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
// MyManagedObject has a custom setters (setPhoto:,setThumb:) that save the
// images to disk and store the file path in the database
object.photo = image;
object.thumb = image;
NSError *nerror;
if (![[DataStore sharedDataStore].managedObjectContext save:&nerror]) {
NSLog(@"Whoops, couldn't save: %@", [nerror localizedDescription]);
return;
}
// notify the table view to reload the table
[[NSNotificationCenter defaultCenter] postNotificationName:@"ReloadTableView" object:nil];
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
NSLog(@"Error getting photo");
}];
[operation start];
}