为UITableView的NSFetchedResultsController多个实体(NSFetc

2019-09-01 05:25发布

我有两个实体的一个叫后和一个叫做用户。 交<< ---->用户在核心数据的关系。 我使用的是NSFetchedResultsController来获取在我的核心数据堆栈中的所有帖子记录,然后在一个UITableView显示它们。 每个小区具有的图像和该图像对应于User.profilePicture。

在初始化我不从服务器上下载的资料图片,我只当它滚动过去认为细胞(延迟加载)下载。 有一次,我下载我下载的图像保存到核心数据堆栈相应User.profilePicture。

是否有controllerDidChangeContent的方式,当我更新了用户实体被称为? 我现在的理解是,我NSFetchedResultsController只能跟着邮政实体,因为这是我最初把它做的,整个的关系无法遍历和更新监测,是真的吗?

Answer 1:

可悲的是我只知道对这个问题的丑陋的解决方案。

在您的User .m文件实现setProfilePicture:是这样的:

//NOT TESTED IN A MULTITHREADED ENV
- (void) setProfilePicture:(NSData *)data
{
    [self willChangeValueForKey:@"profilePicture"];
    [self setPrimitiveValue:data forKey:@"profilePicture"];
    [self.posts enumerateObjectsUsingBlock:^(Post* p, BOOL *stop) {
        [p willChangeValueForKey:@"user"];
        [p didChangeValueForKey:@"user"];
    }];
    [self didChangeValueForKey:@"profilePicture"];
}

这将通知FRC,邮政元素都有变化。

您可能会发现更多的信息在这里

编辑:

获取上访问你可以添加到您的数据User .M:

//UNTESTED
+ (void) mergeToMain:(NSNotification*)notification
{
    AppDelegate* appDel = (AppDelegate*)[[UIApplication sharedApplication] delegate];
    [appDel.managedObjectContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) 
                                                  withObject:notification 
                                               waitUntilDone:YES];
}

- (NSData*)_profilePicture
{
    return [self primitiveValueForKey:@"profilePicture"];
}

- (NSData*) profilePicture
{
    [self willAccessValueForKey:@"profilePicture"];
    NSData* picData = [self primitiveValueForKey:@"profilePicture"];
    if (!name) {
        __block NSManagedObjectID* objectID = self.objectID;
        //This solves the multiple downloads per item by using a single queue
        //for all profile pictures download.
        //There are more concurrent ways to accomplish that
        dispatch_async(downloadSerialQueue, ^{ //define some serial queue for assuring you down download multiple times the same object
            NSError* error = nil;
            AppDelegate* appDel = (AppDelegate*)[[UIApplication sharedApplication] delegate];
            NSManagedObjectContext* context = [[NSManagedObjectContext alloc] init];
            [context setPersistentStoreCoordinator:appDel.persistentStoreCoordinator];
            [context setUndoManager:nil];
            User* user = (User*)[context existingObjectWithID:objectID error:&error];
            if (user && [user _profilePicture] == nil) {
                NSData *data = //[method to retrieve data from server];
                if (data) {
                    if (user) {
                        user.profilePicture = data;
                    } else {
                        NSLog(@"ERROR:: error fetching user: %@",error);
                        return;
                    }
                    [[NSNotificationCenter defaultCenter] addObserver:[self class] selector:@selector(mergeToMain:) name:NSManagedObjectContextDidSaveNotification object:context];
                    [context save:&error];
                    [[NSNotificationCenter defaultCenter] removeObserver:[self class] name:NSManagedObjectContextDidSaveNotification object:context];
                }                    
            }
        });
    }
    [self didAccessValueForKey:@"profilePicture"];
    return picData;
}


Answer 2:

我认为这个问题可以不NSFetchedResultsController参与来解决。

  1. 使用SDWebImage ,SDWebImage可以异步加载从远程服务器映像,只是这样做:

     [myImageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] placeholderImage:[UIImage imageNamed:@"placeholder.png"]]; 
  2. 使用KVO,添加一个观察者用户实体和相应地更新对应的图像图。 但是对于志愿的代码是相当复杂的, ReactiveCocoa可以简化它们:

     [RACAble(user.profilePicture) subscribeNext:^(UIImage *image) { [myImageView setImage:image]; }]; 


文章来源: NSFetchedResultsController multiple entities for UITableView