1

我正在使用 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];
}

这是与我的托管对象中的设置器相关的示例代码

- (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、核心数据和消息传递在线程安全方面的含义。任何想法?

4

2 回答 2

4

AFAIK,您执行请求的方式不正确:

[operation start];

您应该改为将操作添加到NSOperationQueue

    NSOperationQueue* operationQueue = [[NSOperationQueue alloc] init];
    [operationQueue addOperation:operation];

(您应该正确地对队列进行内存管理)。

通过这样做,您的请求将以异步方式执行,它不会阻塞 UI,您也不需要处理多线程。

于 2012-04-09T19:10:19.753 回答
3

根据马特的建议,我通过修改我的调用来改进 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];
}
于 2012-05-23T19:37:32.807 回答