Основные данные: setPrimitiveValue:forKey: ведет себя очень странно
Это загадка
Я призываю setPrimitiveValue:forKey:
на NSManagedObject
, Ключ является законным, постоянным, смоделированным атрибутом объекта. Однако setPrimitiveValue:forKey: fails, часто устанавливая значение для другого произвольного атрибута. Документы говорят, что такое поведение ожидается при вызове setPrimitiveValue:forKey:
для немоделированного ключа. Похоже, что Core Data думает, что ключ не смоделирован.
Странная часть:
Когда ключ жестко закодирован как строковый литерал, значение примитива действительно установлено успешно. Сбой возможен только тогда, когда ключ является переменной. Переменная, которую я использую, передается из keyPath
аргумент observeValueForKeyPath:ofObject:change:context:
keyPath
переменная такая же, как строковый литерал. isEqual:
возвращает true и значения хеша равны. keyPath
переменная имеет тип __NSCFString
, Кто-нибудь знает почему setPrimitiveValue:forKey:
будет вести себя по-другому? (Это поведение на OS X 10.9.1)
Обновление с лучшей информацией:
Ключ неверного поведения восходит к строке, загруженной из файла на диске. Пример ниже является единичным случаем. Если строка атрибута "mainAttr" записывается на диск и считывается обратно, то setPrimitiveValue:forKey:
устанавливает значение для неправильного атрибута, а не "mainAttr".
Базовый объект данных:
@interface Boo : NSManagedObject
@property (nonatomic, retain) NSNumber * mainAttr;
@property (nonatomic, retain) NSNumber * attr1;
@property (nonatomic, retain) NSNumber * attr2;
@property (nonatomic, retain) NSNumber * attr3;
@end
-
#import "Boo.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSManagedObjectContext *context = managedObjectContext();
NSString *key = @"mainAttr";
// write to disk, read back in
NSString *path = [@"~/Desktop/test.txt" stringByExpandingTildeInPath];
[key writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:NULL];
key = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL];
Boo *boo = [NSEntityDescription insertNewObjectForEntityForName:@"Boo" inManagedObjectContext:context];
[boo setPrimitiveValue:@(5) forKey:key];
NSLog(@"Boo: %@", boo);
}
return 0;
}
1 ответ
Вам нужно 3 приведенных ниже утверждения, чтобы установить значение. Попытайся.
[self willChangeValueForKey:key];
[boo setPrimitiveValue:@(5) forKey:key];
[self didChangeValueForKey:key];