【问题标题】:Use Realm data to fill the UITableView (table)?使用 Realm 数据填充 UITableView(表)?
【发布时间】:2017-10-29 18:16:30
【问题描述】:

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

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

注意:我已经读过,如果我在当前线程中获取领域数据,那么我只能在这个线程中使用它们。否则我应该为我需要的每个领域对象创建ThreadSafeReference,并在主线程中重用它。但我不明白该怎么做——这个例子是这样写的,他们在dispatch_async之前创建一个对象并在这个对象中使用它(比如将一个变量传递到代码块中)。

就我而言,我有一个单独的数组,我应该在cellForRowAtIndexPath(不是代码块)中存储和重用它并多次调用。我也不能用我需要的线程调用dispatch_async,因为单元格可能会变得无效。

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

【问题讨论】:

    标签: objective-c swift multithreading uitableview realm


    【解决方案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 无需从其他线程调用领域对象。如果您将视图控制器的引用传递给其他类,例如后台网络客户端或类似的东西,您会得到这些“不正确的线程”错误的唯一情况。

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

    【讨论】:

    • No need to invoke the Realm Objects from other threads of using Dispatch. 我希望你明白 Realm 作为数据库并不是超快的。因此,在更好的情况下,您会在显示视图控制器之前出现延迟,在最坏的情况下,您会遇到不可预知的警告/错误行为,因为您减慢了 viewDidLoad 方法
    • Realm 旨在用作此答案所述。如果您确实有一个项目遇到了这种减速行为,请随时向我们的 GitHub (github.com/realm/realm-cocoa) 提交工单,我们可以修复它揭示的任何错误或帮助您找出您做错了什么。跨度>
    猜你喜欢
    • 2014-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-20
    • 1970-01-01
    • 2020-01-17
    • 1970-01-01
    相关资源
    最近更新 更多