ошибка мы получаем что-то вроде этого:Странный Xcode 4.6 родственный ошибка
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_CDSnapshot_Widget_ unlockObjectStore]: unrecognized selector sent to instance 0x1c5a4350'
иногда класс Widget отправляется, что селектор, иногда это __NSCFString, иногда авария это:
[NSManagedObjectContext unlockObjectStore]: message sent to deallocated instance 0x1ec658c0
Я думаю, что я сузился там, где проблема, но я понятия не имею, почему этот код вызывает это. Вот пример структуры наших классов доступа к данным:
// DataController.m
static NSPersistentStoreCoordinator *_persistentStoreCoordinator;
static NSManagedObjectModel *_managedObjectModel;
static NSManagedObjectContext *_mainManagedObjectContext;
@implementation DataController
- (NSManagedObjectContext *) privateManagedObjectContext {
return [DataController buildManagedObjectContextForConcurrencyType:NSPrivateQueueConcurrencyType];
}
- (NSManagedObjectContext *) defaultManagedObjectContext {
return [self managedObjectContextForConcurrencyType: self.defaultConcurrencyType];
}
- (NSManagedObjectContext *) managedObjectContextForConcurrencyType: (NSManagedObjectContextConcurrencyType) type {
if (type == NSMainQueueConcurrencyType)
return [self mainManagedObjectContext];
else if (type == NSPrivateQueueConcurrencyType)
return [self privateManagedObjectContext];
return nil;
}
// calling _dataController.defaultManagedObjectContext from within the Widgets class
// essentially calls this method for a new context using NSPrivateQueueConcurrencyType as
// the type parameter
+ (NSManagedObjectContext *) buildManagedObjectContextForConcurrencyType: (NSManagedObjectContextConcurrencyType) type {
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType: type];
[context setUndoManager: nil];
[context setMergePolicy: NSMergeByPropertyObjectTrumpMergePolicy];
[context setPersistentStoreCoordinator: _persistentStoreCoordinator];
return context;
}
@end
и наш класс виджетов
// Widgets.m
static DataController *_dataController;
@implementation Widgets
+ (void) initialize {
_dataController = [[DataController alloc] init];
}
+ (NSArray *)certainWidgets {
return [self certainWidgetsInManagedObjectContext:_dataController.defaultManagedObjectContext];
}
+ (NSArray *) certainWidgetsInManagedObjectContext: (NSManagedObjectContext *) context {
// boiler plate CoreData fetching code
}
@end
Это пример кода используется для извлечения виджетов
dispatch_async(dispatch_get_global_queue(0, 0), ^{
for (Widget *w in [Widgets certainWidgets]) {
if ([w.isValid intValue]) {
// do something extraoridarily fantastic with the widget
}
}
});
Это происходит только в Xcode 4.6, режим Release (не в Debug). Мы ничего не видим в примечаниях к выпуску Xcode 4.6, которые дадут нам ключ к тому, что происходит.
Я подозреваю, что проблема связана с тем, как мы структурировали наш класс доступа к данным (DataController) в сочетании с тем фактом, что мы используем методы класса для обработки всего доступа к данным в классе Widgets. Причина моего подозрения в том, что, когда мы удаляем методы класса из класса Widgets и вместо этого делаем им методы экземпляра, избавляемся от метода + initialize и настраиваем NSManagedObjectContext для каждого экземпляра класса Widgets, проблема, похоже, идет далеко.
Просто, чтобы уточнить, я думаю, что исправил проблему, но мне неудобно отталкивать исправление, пока я не пойму, почему вышеупомянутые изменения исправить. Похоже, что есть какая-то проблема с памятью или неправильная парадигма программирования, которую мы не улавливаем. Любые указатели?