未为 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()