4

У меня есть класс DataManager, который возвращает общий экземпляр:Основные данные IOS 8 Сегодня Widget вопрос

+ (DataManager *)sharedInstance; 
{ 
    static DataManager *sharedInstance = nil; 
    static dispatch_once_t pred; 

    dispatch_once(&pred, ^{ 
     sharedInstance = [[DataManager alloc] init]; 
    }); 

    return sharedInstance; 
} 

В здесь я уследить моего managedObjectContext, managedObjectModel, persistentStoreCoordinator.

У меня также есть метод, где я вытаскивать элементы для отображения:

- (NSArray *)getItems 
{ 
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Item"]; 
    return [[self managedObjectContext] executeFetchRequest:fetchRequest error:nil]; 
} 

Теперь в моем главном приложении у меня есть контроллер представления, когда я называю это GetItems, а затем изменить элементы по отдельности. Так, например, set item.itemName = @ "testName"; а затем вызовите мой метод сохранения.

У меня также есть iOS 8, где в моем TodayViewController я также называю метод getItems. У меня есть NSNotification, которая обнаруживает, что для managedObjectContext сохраняет.

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refetchItems) name:NSManagedObjectContextDidSaveNotification object:[[DataManager sharedInstance] managedObjectContext]]; 

Эти переназначенные элементы вызываются, но возвращают устаревшие объекты NSManagedObjects. Так, например, itemName не изменилось на @ "testName".

Куда я иду не так? Дайте мне знать, если вам нужно увидеть какой-либо другой код.

Спасибо!

+0

Ваше приложение и виджет запуска в разные процессы. Если ваше приложение изменит основное хранилище данных, ваш виджет не получит уведомление, отправленное из приложения. – quellish

+0

@quellish, что является лучшим способом для обнаружения изменений? – Stephen

+1

У меня точно такая же проблема, но и не нашли решения. Только я могу думать о том, что нужно «разрушить» контекст и создать его снова. –

ответ

7

Вы можете попробовать следующее для обновления определенного ManagedObject. И если вы хотите обновить список ManagedObject, тогда сверните каждый объект и выполните команду.

[_managedObjectContext refreshObject:act mergeChanges:YES]; 

Или для IOS Verion 8.3 и выше вы можете использовать следующий метод для обновления всех ManagedObject в контексте сразу следующим образом.

[_managedObjectContext refreshAllObjects]; 

Он работает немного, но только для данных UPDATE, а не для добавления или удаления данных.

Если он не работает, вы можете также добавить

[_managedObjectContext reset]; 

после этого, вы должны читать «переназначить» все переменные, которые вы загрузили из вашего основного хранилища данных.

Другого решения (более медленное и некрасиво)

Если выше не работает, другое решение будет удалить текущий контекст и создать его заново.

Я просто установить

_persistentStoreCoordinator = nil; 
_managedObjectModel = nil; 
_managedObjectContext = nil; 

У меня есть класс CoreDataManager с этим свойствам

@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel; 
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext; 
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator; 

А в классе я вручную создал сеттеров. Если я запишу все переменные, из-за сеттеров, они снова будут заменены после того, как я прочитаю их за пределами моего основного класса диспетчера данных.

Вы можете улучшить это, используя NSUserDefault магазин. Он обновляется правильно. В главном приложении, если вы измените что-то, установите флаг в NSUserDefault.В расширении прочитайте это, и если флаг отмечен, сбросьте основные данные. Таким образом, вы сэкономите некоторые тики и сделаете что-то быстрее.

Для выделения NSUserDefault (в обоих приложениях - расширение и основной) использовать это - после этого, вы можете считывать данные из него, как usuall и они должны быть синхронизированы

NSUserDefaults *prefs = [[NSUserDefaults alloc] initWithSuiteName:GROUP_NAME]; //share with extension 
+0

большое спасибо за то, что вы положили в это! – Stephen