0

我有一个用NSDataproperty定义的 Core Data 实体imageDataimage我在实体上有一个 setter 和 getter 设置。

setter, setImage, 只是调用[self setImageData:UIImagePNGRepresentation(img)]; getter, image, 只是返回[UIImage imageWithData:[self imageData]];

当我创建一个新实体并且我的获取结果控制器加载新表行时,图像总是拉 null。但是,如果我点击该行以转到下一个视图控制器,则图像显示得很好

我该怎么做才能让它在保存发生后立即显示图像,并且 fetchResultsController 使用新行更新。

编辑:添加代码

图像片段的核心数据头和 getter/setter

.h
@property (nonatomic, retain) NSData * imageData;

@property (nonatomic, retain) UIImage *image;

.m
- (void)setImage:(UIImage *)image
{
    NSData *data = UIImagePNGRepresentation(image);
    [self setImageData:data];
}

- (UIImage *)image
{
    return [UIImage imageWithData:[self imageData]];
}

表视图代码

- (NSFetchedResultsController *)fetchedResultsController {

    if (_fetchedResultsController != nil) {
        return _fetchedResultsController;
    }

    [NSFetchedResultsController deleteCacheWithName:@"Artists"];

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"ArtistModel" inManagedObjectContext:[[BKDataManager sharedInstance] mainObjectContext]];
    [fetchRequest setEntity:entity];

    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];

    [fetchRequest setFetchBatchSize:20];

    _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[[BKDataManager sharedInstance] mainObjectContext] sectionNameKeyPath:nil cacheName:@"Artists"];

    _fetchedResultsController.delegate = self;

    return _fetchedResultsController;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    ArtistTableViewCell *cell = (ArtistTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"ArtistsTableViewCell"];

    if(!cell) {
        cell = (ArtistTableViewCell *)[[[UINib nibWithNibName:@"ArtistTableViewCell" bundle:nil] instantiateWithOwner:nil options:nil] objectAtIndex:0];
    }

    ArtistModel *row = [[self fetchedResultsController] objectAtIndexPath:indexPath];

    [[cell artistNameLabel] setText:[row name]];
    [[cell artistImageView] setImage:[row image]]; // This is where it pulls from the artist model

    return cell;
}

保存到核心数据位

- (void)addArtistWithName:(NSString *)name confirmed:(BOOL)confirmed managedContext:(NSManagedObjectContext *)managedContext success:(BKClientIdResult)success failure:(BKClientError)failure
{
    NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
                            name, @"name",
                            [NSNumber numberWithBool:confirmed], @"confirmed"
                            , nil];

    [[BKClient sharedInstance] postPath:@"/users/artists" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
        if([[responseObject objectForKey:@"status"] boolValue]) {
            NSDictionary *result = [responseObject valueForKeyPath:@"payload.artist"];

            ArtistModel *artistModel = (ArtistModel *)[NSEntityDescription insertNewObjectForEntityForName:@"ArtistModel" inManagedObjectContext:managedContext];

            [artistModel setName:[result objectForKey:@"name"]];

                NSURLRequest *imageRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:[result objectForKey:@"image"]]];

                AFImageRequestOperation *op = [AFImageRequestOperation imageRequestOperationWithRequest:imageRequest imageProcessingBlock:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
                    [artistModel setImage:image];

                    [managedContext save:nil];

                    if(success) {
                        success(artistModel);
                    }
                } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
                    // TODO FIX
                }];

                [op start];
        } else {
            if(failure) {
                failure([NSError errorWithDomain:@"com.nf" code:0 userInfo:[responseObject objectForKey:@"error"]]);
            }
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        if(failure) {
            failure(error);
        }
    }];
}
4

2 回答 2

1

根据您的问题,刷新数据的最简单方法是执行新的提取(通过NSFetchedResultsController)并在完成保存后重新加载表视图。

NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
    // error handling here...
}

[yourTableView reloadData];

或者,您可以考虑为您的NSFetchedResultsController. 有关更多信息,请查看NSFetchedResultsControllerDelegate 文档core-data-tutorial-how-to-use-nsfetchedresultscontroller

设置此委托,它允许您侦听托管上下文的更改并正确响应表视图修改(添加、删除、更新部分和行)。

PS如果您提供一些代码,我们将能够以更详细的方式为您提供帮助。

于 2012-12-26T09:22:07.230 回答
0

您可以使用NSValueTransformer轻松地将图像存储到 CoreData 中(使用Transformabletype 而不是NSData):

。H

@interface ImageToDataTransformer : NSValueTransformer

@end

.m

#import "DataTransformer.h"

@implementation ImageToDataTransformer

#pragma mark - UIImage to NSData

+ (BOOL)allowsReverseTransformation {
  return YES;
}

+ (Class)transformedValueClass {
  return [NSData class];
}

- (id)transformedValue:(id)value {
  NSData * data = UIImagePNGRepresentation(value);
  return data;
}

- (id)reverseTransformedValue:(id)value {
  UIImage * image = [[UIImage alloc] initWithData:value];
  return [image autorelease];
}

@end

并且不要忘记将您的属性设置为Transformable类型,然后在“数据模型检查器”中,将名称设置为ImageToDataTransformer.

于 2012-12-26T09:22:17.730 回答