未为 API 侦听器调用 NSFetchedResultsController 委托

Posted

技术标签:

【中文标题】未为 API 侦听器调用 NSFetchedResultsController 委托【英文标题】:NSFetchedResultsController delegate not called for API listener 【发布时间】:2013-06-17 15:23:13 【问题描述】:

如果代码将委托分配给NSFetchedResultsController,如下所示:

-(id)initWithFetchedResultsController:(NSFetchedResultsController*)fetchedResultsController

    self = [super init];
    if (self != nil)
    
        fetchedResultsController.delegate = self;
        _fetchedResultController = fetchedResultsController;
    
    return self;

NSFetchedResultsControllerDelegate 方法 – controller:didChangeObject:atIndexPath:forChangeType:newIndexPath: 从未在 self 上调用:

-(void)controller:(NSFetchedResultsController *)controller
  didChangeObject:(id)anObject
      atIndexPath:(NSIndexPath *)indexPath
    forChangeType:(NSFetchedResultsChangeType)type
     newIndexPath:(NSIndexPath *)newIndexPath

    NSLog(@"Delegate method called"); // Never called

谓词没有问题,分配了一个谓词,直接使用通知即可。

【问题讨论】:

就我而言,我忘了调用NSFetchedResultsController.performFetch() 【参考方案1】:

问题是初始- (BOOL)performFetch:(NSError **)error 从未被调用,因为此特定代码只关心结果集的更改,而不是初始集。然而,随之而来的是控制器不会注意到它从未有过的数据的变化。如下更改 init 方法可解决问题:

-(id)initWithFetchedResultsController:(NSFetchedResultsController*)fetchedResultsController

    self = [super init];
    if (self != nil)
    
        fetchedResultsController.delegate = self;
        _fetchedResultController = fetchedResultsController;
        [fetchedResultsController performFetch:nil];
    
    return self;

【讨论】:

【参考方案2】:

我有一个带有委托集的NSFetchedResultsController,并执行了performFetch。 并且仍然没有调用委托方法。

我的 Fetched Results Controller 有一个 sectionNameKeyPath,它是一个布尔值。我以非原始身份访问 - 作为NSNumber

我插入和更新的所有实体都有这个属性nil。我原以为 nil 会被解释为 NO,但事实并非如此。

当我插入一个此属性为 nil 的实体时,根本不会调用 fetched results 控制器委托方法。 它会简单地忽略此记录,就像它与我的 FRC 无关。

所以,我确保我永远不会在用作 sectionNameKeyPath 的属性中放置 nil。

【讨论】:

【参考方案3】:

我遇到过同样的问题,我正在分享我的经验。 也许它可以帮助某人。

我确实有“消息”NSManagedObject 类。

如果我们确实有如下属性:

@NSManaged public var buddyId: Int32
@NSManaged public var message: NSObject?
@NSManaged public var messageServerId: Int32
@NSManaged public var messageUnixTime: Double
@NSManaged public var sender: Int32
@NSManaged public var status: Int32
@NSManaged public var type: Int32
@NSManaged public var userId: Int32
@NSManaged public var buddyName: String?
@NSManaged public var chatroomId: Int32
@NSManaged public var messageSource: Int32

你的谓词是这样的:

fetchRequest.predicate = NSPredicate(format: "userId == %@ AND buddyId == %@ AND messageSource == %d", userId, buddyId, 10)

因此,在这种情况下,我们确实将 userId 作为 Int32,但我们将其作为字符串传递给谓词。 NSFetchedResultsController 在 mainContext 上,所有消息(数据)处理都在 privateConext(mainContext 的子上下文)上进行。

所以 NSFetchedResultsController 会在 performFetch() 调用中获取所有消息,但是当我们在 privateContext 上对消息进行任何插入/更新/删除操作时,这些操作效果不会反映到 NSFetchedResultsController。

原因很简单,因为我没有提供正确的谓词。

我确实需要修改谓词,例如:

fetchRequest.predicate = NSPredicate(format: "userId == '%@' AND buddyId == '%@' AND messageSource == %d", userId, buddyId, 10)

或者我确实需要提供如下谓词:

fetchRequest.predicate = NSPredicate(format: "userId == %d AND buddyId == %d AND messageSource == %d", userId, buddyId, 10)

原因是“userId”,而“buddyId”是 Int32 类型,但我在谓词中将它们作为字符串提供。因此 NSFetchedResultsController 无法检测到消息更改。

就是这样。

如果有人需要对此进行详细讨论,请告诉我。

希望这会对某人有所帮助。

【讨论】:

以上是关于未为 API 侦听器调用 NSFetchedResultsController 委托的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security OAuth - 未为空资源配置提供程序管理器

Spring Security OAuth - 未为空资源配置提供程序管理器

未为 InvoiceTemplateGet 类型定义方法 execute()

Dio 在 Scroll Controller 监听器中进行了许多 API 调用

未为 Google OAUTH 登录配置访问权限

如何在 heroku 上运行带有事件机侦听器的 ruby​​ 脚本?