Я использую тот же NSFetchedResultsController, чтобы захватить некоторые результаты из основных данных, поддержанных sqllite через RESTKit, которые распределяются между несколькими контроллерами отображения:CoreData + RESTKit: несколько копий одного и того же объекта от NSFetchedResultsController
NSFetchedResultsController* _fetchedResultsController;
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"User"];
fetchRequest.sortDescriptors = @[[[NSSortDescriptor alloc] initWithKey:@"username" ascending:YES]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"current == YES"];
[fetchRequest setPredicate:predicate];
_fetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:[self __getContext]
sectionNameKeyPath:nil cacheName:@"currentUser"];
_fetchedResultsController.delegate = self;
[_fetchedResultsController performFetch:error];
NSArray *array = [_fetchedResultsController fetchedObjects];
return array;
Это вызывается на нескольких этапах во время выполнения приложения, однако, несмотря на то, что я указываю имя кеша, я получаю несколько копий одного и того же объекта, т. е. не единственный источник правды.
Эта проблема возникает только при перезагрузке приложения. Не проблема при первоначальном отображении объектов.
Я что-то упустил? Заранее спасибо
Edit:
Первый некоторый контекст:
Я отмечаю, вошедший в системе пользователя с текущим атрибутом, и любое представление контроллеры, которым необходим доступ к текущему пользователю будут выполнять закэшированную выборку запроса ,
В какой-то момент на раннем этапе приложения один контроллер вида добавляет себя в качестве наблюдателя к текущему пользователю, который получен из этого запроса на выборку. В другой момент выполнения приложений пользователь создает альбом, после которого запрос выборки выполняется снова. На этот раз адрес памяти объекта отличается, и первый контроллер представления не получает уведомление KVO, когда альбом добавляется к атрибуту set users.
Вот некоторые дополнительные журналы, которые показывают, что RKInMemoryManagedObjectCache начинает возвращать другой объект пользователя:
2014-02-15 16:15:53.196 [22074:a0b] user init: 0xf090b60 <x-coredata://56C4885F-954C-4843-9A59-52133777ECC5/User/p2><robbie> in context <NSManagedObjectContext: 0xf079790>
2014-02-15 16:15:53.198 [22074:a0b] [<RKInMemoryManagedObjectCache: 0xf0593b0>] In memory object cache is returning 0xf090b60 <x-coredata://56C4885F-954C-4843-9A59-52133777ECC5/User/p2><robbie> as current user
2014-02-15 16:15:53.209 [22074:a0b] [<RKInMemoryManagedObjectCache: 0xf0593b0>] In memory object cache is returning 0xf090b60 <x-coredata://56C4885F-954C-4843-9A59-52133777ECC5/User/p2><robbie> as current user
2014-02-15 16:15:53.209 [22074:a0b] [AlbumCollectionViewController] observing user 0xf090b60 <x-coredata://56C4885F-954C-4843-9A59-52133777ECC5/User/p2>: robbie
2014-02-15 16:15:53.209 [22074:a0b] [<RKInMemoryManagedObjectCache: 0xf0593b0>] In memory object cache is returning 0xf090b60 <x-coredata://56C4885F-954C-4843-9A59-52133777ECC5/User/p2><robbie> as current user
2014-02-15 16:15:53.262 [22074:a0b] [<RKInMemoryManagedObjectCache: 0xf0593b0>] In memory object cache is returning 0xf090b60 <x-coredata://56C4885F-954C-4843-9A59-52133777ECC5/User/p2><robbie> as current user
2014-02-15 16:15:53.262 [22074:a0b] [<RKInMemoryManagedObjectCache: 0xf0593b0>] In memory object cache is returning 0xf090b60 <x-coredata://56C4885F-954C-4843-9A59-52133777ECC5/User/p2><robbie> as current user
2014-02-15 16:15:53.269 [22074:a0b] [<RKInMemoryManagedObjectCache: 0xf0593b0>] In memory object cache is returning 0xf090b60 <x-coredata://56C4885F-954C-4843-9A59-52133777ECC5/User/p2><robbie> as current user
2014-02-15 16:15:53.269 [22074:a0b] [<RKInMemoryManagedObjectCache: 0xf0593b0>] In memory object cache is returning 0xf090b60 <x-coredata://56C4885F-954C-4843-9A59-52133777ECC5/User/p2><robbie> as current user
2014-02-15 16:15:53.278 [22074:a0b] applicationDidBecomeActive
2014-02-15 16:15:53.329 [22074:a0b] user init: 0xf342590 <x-coredata://56C4885F-954C-4843-9A59-52133777ECC5/User/p2><robbie> in context <NSManagedObjectContext: 0xf079790>
2014-02-15 16:15:53.329 [22074:a0b] [<RKInMemoryManagedObjectCache: 0xf0593b0>] In memory object cache is returning 0xf342590 <x-coredata://56C4885F-954C-4843-9A59-52133777ECC5/User/p2><robbie> as current user
2014-02-15 16:15:53.329 [22074:a0b] [<RKInMemoryManagedObjectCache: 0xf0593b0>] In memory object cache is returning 0xf342590 <x-coredata://56C4885F-954C-4843-9A59-52133777ECC5/User/p2><robbie> as current user
2014-02-15 16:15:53.346 [22074:a0b] [<RKInMemoryManagedObjectCache: 0xf0593b0>] In memory object cache is returning 0xf342590 <x-coredata://56C4885F-954C-4843-9A59-52133777ECC5/User/p2><robbie> as current user
2014-02-15 16:15:53.348 [22074:a0b] [<RKInMemoryManagedObjectCache: 0xf0593b0>] In memory object cache is returning 0xf342590 <x-coredata://56C4885F-954C-4843-9A59-52133777ECC5/User/p2><robbie> as current user
Он всегда кажется, что начать возвращать что-то другое, как только applicationDidBecomeActive называется, как ни странно.
Edit2:
стеквызовов, ведущих к первому пользователя INIT:
#0 0x000e87f0 in -[User initWithEntity:insertIntoManagedObjectContext:] at /Users/mtford/Playground/App/App/App/CoreData/Human/User.m:107
#1 0x00f68a89 in -[NSManagedObject(_NSInternalMethods) _initWithEntity:withID:withHandler:withContext:]()
#2 0x00f66ff2 in -[NSManagedObjectContext(_NSInternalAdditions) _retainedObjectWithID:optionalHandler:withInlineStorage:]()
#3 0x00fb69b4 in _PFRetainedObjectIDCore()
#4 0x00fb6880 in -[NSManagedObjectContext(_NSInternalAdditions) _retainedObjectWithID:]()
#5 0x00fa7724 in -[NSManagedObjectContext(_NestedContextSupport) _parentObjectsForFetchRequest:inContext:error:]()
#6 0x010251f4 in __82-[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:]_block_invoke()
#7 0x00fa7321 in internalBlockToNSManagedObjectContextPerform()
#8 0x035fb4b0 in _dispatch_client_callout()
#9 0x035e8778 in _dispatch_barrier_sync_f_invoke()
#10 0x035e8422 in dispatch_barrier_sync_f()
#11 0x00fa72a2 in _perform()
#12 0x00fa714e in -[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:]()
#13 0x00f526c6 in -[NSManagedObjectContext executeFetchRequest:error:]()
#14 0x00276367 in __96-[RKInMemoryManagedObjectCache managedObjectsWithEntity:attributeValues:inManagedObjectContext:]_block_invoke_2 at /Users/mtford/Playground/App/App/Pods/RestKit/Code/CoreData/RKInMemoryManagedObjectCache.m:112
#15 0x00fa6fef in developerSubmittedBlockToNSManagedObjectContextPerform()
#16 0x00fa6f2c in -[NSManagedObjectContext performBlockAndWait:]()
#17 0x00275ce4 in -[RKInMemoryManagedObjectCache managedObjectsWithEntity:attributeValues:inManagedObjectContext:] at /Users/mtford/Playground/App/App/Pods/RestKit/Code/CoreData/RKInMemoryManagedObjectCache.m:109
#18 0x000d73d9 in -[RestKitInterface getCurrentUsersWithError:] at /Users/mtford/Playground/App/App/App/RESTKit/Old/RestKitInterface.m:647
#19 0x000e9613 in +[User currentUser] at /Users/mtford/Playground/App/App/App/CoreData/Human/User.m:221
#20 0x0002f6f0 in -[TabBarController viewWillAppear:] at /Users/mtford/Playground/App/App/App/View Controllers/AppTabBarController.m:100
стек вызовов, ведущих ко второму пользователя INIT:
#0 0x000e87f0 in -[User initWithEntity:insertIntoManagedObjectContext:] at /Users/mtford/Playground/App/App/App/CoreData/Human/User.m:107
#1 0x00f68a89 in -[NSManagedObject(_NSInternalMethods) _initWithEntity:withID:withHandler:withContext:]()
#2 0x00f66ff2 in -[NSManagedObjectContext(_NSInternalAdditions) _retainedObjectWithID:optionalHandler:withInlineStorage:]()
#3 0x00fb69b4 in _PFRetainedObjectIDCore()
#4 0x00f7ffbf in -[NSManagedObjectContext(_NSInternalAdditions) _retainedObjectWithID:error:]()
#5 0x00f7fef5 in -[NSManagedObjectContext existingObjectWithID:error:]()
#6 0x0025e29a in __56-[RKEntityByAttributeCache objectForObjectID:inContext:]_block_invoke at /Users/mtford/Playground/App/App/Pods/RestKit/Code/CoreData/RKEntityByAttributeCache.m:222
#7 0x00fa6fef in developerSubmittedBlockToNSManagedObjectContextPerform()
#8 0x00fa6f2c in -[NSManagedObjectContext performBlockAndWait:]()
#9 0x0025dd7c in -[RKEntityByAttributeCache objectForObjectID:inContext:] at /Users/mtford/Playground/App/App/Pods/RestKit/Code/CoreData/RKEntityByAttributeCache.m:221
#10 0x0025ea74 in -[RKEntityByAttributeCache objectsWithAttributeValues:inContext:] at /Users/mtford/Playground/App/App/Pods/RestKit/Code/CoreData/RKEntityByAttributeCache.m:255
#11 0x00265644 in -[RKEntityCache objectsForEntity:withAttributeValues:inContext:] at /Users/mtford/Playground/App/App/Pods/RestKit/Code/CoreData/RKEntityCache.m:90
#12 0x00275f15 in -[RKInMemoryManagedObjectCache managedObjectsWithEntity:attributeValues:inManagedObjectContext:] at /Users/mtford/Playground/App/App/Pods/RestKit/Code/CoreData/RKInMemoryManagedObjectCache.m:132
#13 0x000d73d9 in -[RestKitInterface getCurrentUsersWithError:] at /Users/mtford/Playground/App/App/App/RESTKit/Old/RestKitInterface.m:647
#14 0x000e9613 in +[User currentUser] at /Users/mtford/Playground/App/App/App/CoreData/Human/User.m:221
#15 0x00003efb in -[AlbumCollectionViewController observeValueForKeyPath:ofObject:change:context:] at /Users/mtford/Playground/App/App/App/View Controllers/AlbumCollectionViewController.m:179
Можете ли вы показать пример дубликатов, как вы их проверяете/сравниваете? – Wain
Привет, Уэйн, добавлен в вопрос. – Michael
Я сделал еще несколько исследований, и кажется, что в кеше объектов памяти создается новый объект после вызова applicationDidBecomeActive. Не уверен, что это совпадение ... – Michael