使用Realm数据填充UITableView(表)?

时间:2017-10-29 18:16:31

标签: objective-c swift multithreading uitableview realm

我的解决方案不起作用 - 我使用realm将数据存储为数组并在cellForRowAtIndexPath:中重用此数组。

问题是我应该在后台线程中获取数据,但在主线程中填充表。

注意:我已经读过如果我在当前线程中获取领域数据,那么我只能在这个线程中使用它们。否则我应该为我需要的每个领域对象创建ThreadSafeReference并在主线程中重用它。但是我无法理解如何去做 - 这个例子的编写方式是它们在dispatch_async之前创建一个对象并在这个对象中使用它(比如将一个变量传递给代码块)。

在我的情况下,我有一个单独的数组,我应该在cellForRowAtIndexPath(这不是代码块)中存储和重用,并多次调用。我也无法使用我需要的线程调用dispatch_async,因为该单元格可能无效。

如何解决这个问题?我应该手动缓存Realm对象吗?我同时接受Swift和Objective-C语言

1 个答案:

答案 0 :(得分:1)

以下代码适合您:

// ViewController.h
#import <UIKit/UIKit.h>
#import "MyObject.h" // subclass of RLMObject

@interface MyViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

@property (weak, nonatomic) IBOutlet UITableView *myTableView;
@property RLMResults<MyObject *> *objectsList;

@end

实施:

// ViewController.m
#import "MyViewController.h"

@implementation MyViewController {

- (void)viewDidLoad {
    _objectsList = [MyObject allObjects]; // optionally sort, query, etc.
}

- (void)viewDidAppear {
    [super viewDidAppear];
    // Do any other setup
}

#pragma mark - UITableViewDataSource

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return _objectsList.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // Setup the cell with the object's information. It's up to you how 
    // to do it. Register a custom subclass of UITableViewCell, for example.
    MyObject *thisCellObject = [objectsList objectAtIndex:indexPath.row];
    UITableViewCell *cell = [self.myTableView dequeueReusableCellWithIdentifier:@"customIdentifier"];

    // Title should be a property on your MyObject class
    cell.textLabel.text = thisCellObject.title;
}

#pragma mark - UITableViewDelegate

// Implement the Delegate methods as you want it...
}

无需从使用Dispatch的其他线程调用Realm对象。如果您将视图控制器中的引用传递给其他类,例如后台网络客户端或类似的东西,那么您将获得这些“不正确的线程”错误的唯一情况就是。

无论如何,这些案件也是可以避免的。如果你的对象有一个ID,让我们说从API,你将ID传递给另一个类,可能是后台同步客户端,并从该客户端执行对象的查询,如[MyObject objectsWhere:@"objectID == %@", idString];。该对象是从后台进程调用的,它将使用它,因此它不会失败。