2012-04-11 5 views
1

Ich schreibe eine Anwendung mit Core Data, die stark davon abhängt, Attribute aus String-Werten zu setzen. Ich stoße jedoch auf ein Problem, da Core Data beim Erstellen von Wrapper-Methoden NSNumber verwendet, um alle numerischen Felder darzustellen. Daher, wenn ich eine Zeichenfolge mit Schlüssel/Wert-Codierung übergeben SetValue: forKey: Es gibt mir einen Typ Fehler:Key-Value Type Coercion unter iOS

Zum Beispiel habe ich einen Objekttyp "Gebäude". Im Datenmodell, ich habe ein Attribut "fbFloors" auf integer 32.

Dann in meinem Code genannt, ich folgendes tun:

Gebäude * b = [NSEntityDescription insertNewObjectForEntityForName: @ "Gebäude" inManagedObjectContext: ctx]; [b setValue: @ "2" forKey: @ "fbFloors"];

Dies wirft die folgende Ausnahme:

App beenden aufgrund nicht abgefangene Ausnahme ‚NSInvalidArgumentException‘ Grund: ‚Unzulässige Art des Wertes für das Attribut: property =‚fbFloors‘; gewünschter Typ = NSNummer; gegebener Typ = __NSCFConstantString; Wert = 2. '

Ich möchte es den String-Wert zu einer Zahl zwingen, aber es will nicht. Ich habe versucht, coerceValueForFbFloors zu implementieren: aber es scheint, dass das nur in Mac OS X, nicht in iOS verfügbar ist.

Irgendwelche Ideen?

Antwort

0

Sie müssen eine tatsächliche Instanz von NSNumber an setValue übergeben. Etwas wie:

[b setValue [NSNummer numberWithInt: 2] forKey: @ "fbFloors"];

Wenn Ihre Daten als Zeichenfolge angezeigt werden, können Sie NSNumberFormatter verwenden, um sie zuerst in eine NSNumber zu konvertieren.

+0

Der Grund, warum ich das vermeiden wollte, ist, weil ich gehofft habe, direkte Codierung vermeiden zu können. Es gibt viele Felder mit einer Vielzahl von Typen, aber alle kommen über einen Text-Feed herein, also hoffte ich, dass KVC in der Lage sein würde, die Typen zu erzwingen, ohne dass ich manuell codieren musste, was mit jedem Feld passiert. Ich habe darüber nachgedacht, ein Feld namens "fbFloorsString" hinzuzufügen, das die Konvertierung für mich übernimmt, aber ich habe auf eine automatische Art gehofft. – johnnyb

1

Was ist, wenn Sie so etwas wie dies taten ...

- (NSNumber*)fbFloorsValue:(NSString*)valueString 
{ 
    return [NSNumber numberWithInteger: [valueString integerValue]]; 
} 

, wo Sie eine Methode für jedes Nicht-String-Attribut. Dann, wenn Sie diese Werte in allgemeiner Weise eingestellt ...

Angenommen, Ihren Schlüssel („fbFloors“) in einer Variable mit dem Namen und Ihr Wert („2“) ist in einer Variablen namens ...

id valueObject; 
SEL selector = NSSelectorFromString([NSString stringWithFormat:@"%@Value:", key]); 
if (selector && [self respondsToSelector:selector]) { 
    valueObject = [self performSelector:selector withObject:value]; 
} else { 
    valueObject = value; 
} 
Building * b = [NSEntityDescription insertNewObjectForEntityForName:@"Building" inManagedObjectContext:ctx]; [b setValue:valueObject forKey:@key];