【问题标题】:NSFetchResultController for showing records on an Apple Watch?NSFetchedResultsController 用于在 Apple Watch 上显示记录?
【发布时间】:2015-04-08 07:38:21
【问题描述】:

我可以在 Apple Watch 上使用NSFetchResultController 在表格中显示 80 到 90 条记录吗?

我使用WKInterfaceTable+IGInterfaceDataTable 来使用数据源类型加载方法,因为在我看来这比使用NSArray 简单。

NSFetchResultController 会有助于提高效率还是会降低效率?

【问题讨论】:

    标签: ios objective-c nsfetchedresultscontroller apple-watch


    【解决方案1】:

    我发现 NSFetchResultController 在 iWatch 应用程序中根本没有用,因为 WKInterfaceTable 不支持对 NSFetchResultController 在委托中支持的单行进行编辑、更改或删除的委托方法。所以你每次都必须更新你想要显示的所有数据,所以我认为我们不应该使用它。

    【讨论】:

    • 但它使表格的排序变得容易。
    【解决方案2】:

    我在 Apple Watch 应用程序中使用了 NSFetchedResultControllerWKInterfaceTable。确实不如UITableViewController方便,但是非常可行。我没有任何性能问题,即使在加载 20+ 行时(没有尝试 80-90)。当然这是在模拟器中,所以我不知道设备本身会如何表现。

    插入、更新和删除你必须自己实现,但没那么难。

    下面是我在InterfaceController中的部分代码,以插入行为例,但编辑和删除并不难:


    界面

    ...
    @property (weak, nonatomic) IBOutlet WKInterfaceTable *interfaceTable;
    @property(strong, nonatomic) NSFetchRequest *fetchRequest;
    @property(strong, nonatomic) NSFetchedResultsController *fetchedResultsController;
    @property(strong, nonatomic) NSMutableArray *data;
    ...
    

    实施

    获取和往常一样,只是我们没有为结果控制器分配委托,而是直接保存数据:

    self.fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"YourModel" inManagedObjectContext:self.managedObjectContext];
    self.fetchRequest.entity = entityDescription;
    
    [self.fetchRequest setSortDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"createdAt" ascending:YES]]];
    self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:self.fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
    
    [self.fetchedResultsController performFetch:&error];
    self.data= self.fetchedResultsController.fetchedObjects;
    

    然后我使用一个函数loadTableData:

    - (void)loadTableData {
        [self.interfaceTable setNumberOfRows:[[self data] count] withRowType:@"YourCustomCell"];
        [self.interfaceTable insertRowsAtIndexes:[NSIndexSet indexSetWithIndex:[[self data] count]] withRowType:@"YourRowType"];
    
        for (int i = 0; i<[[self data] count];i++)
            [self configureRowControllerAtIndex:i];
    
    }
    

    调用configureRowControllerAtIndex,一个填充一行的函数(我有两个标签):

    - (void)configureRowControllerAtIndex:(NSInteger)index {
        WKTableVIewRowController *listItemRowController = [self.interfaceTable rowControllerAtIndex:index];
    
        [listItemRowController setTitle:[[self.data[index] title] integerValue]];
    
        [listItemRowController setDescription:[self.data[index] description]];
    
    }
    

    插入新行时,只需在数据数组中手动​​添加managedObjectContext

    // Add in managedObjectContext
    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"YourModel" inManagedObjectContext:self.managedObjectContext];
    
    YourModel *newRow = [[YourModel  alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:nil];
    // Add in data array
    [self.data addObject:newRow];
    

    并定期保存 managedObjectContext:

    if (![self.managedObjectContext save:&error]) {
        if (error) {
            NSLog(@"Unable to save changes.");
            NSLog(@"%@, %@", error, error.localizedDescription);
        }
    }
    

    【讨论】:

    • 如何处理 NSFetchResultControllerDelegates 的回调方法?我认为即使添加单个项目,您也需要计算所有行和其他内容,因为 iWatch 为表格显示一次屏幕,而要进行一次更改,您需要再次加载所有表格数据。
    • 现在我在插入、更新、删除后重新加载表,是的。不过,您可以使用 configureRowControllerAtIndex 更新现有行(见上文)。您想使用哪些回调方法? didChangeObject: atIndexPath 等等,您可以在运行 configureRowControllerAtIndex 之后通过执行块(在单独的线程上)来替换。这在 Watch 应用中运行良好。
    【解决方案3】:

    NSFetchedResultsControllerWKInterfaceTable 一起工作是一个PITA。地狱,将普通数组/数据字典映射到WKInterfaceTable 很糟糕。我们构建并开源了一个简单的库来简化此操作,至少使 API 类似于UITableView。刚刚获得了一些外部帮助,增加了对 NSFetchedResultsController 的支持。希望这对未来有帮助!

    https://github.com/Instagram/IGInterfaceDataTable

    【讨论】:

      猜你喜欢
      • 2019-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-18
      相关资源
      最近更新 更多