2009-06-20 7 views
14

Utilizzo i dati del core a livello di codice (ovvero non utilizzo dei file del modello di dati .xcdatamodel) nello stesso modo illustrato in Core Data Utility Tutorial di Apple. Quindi il mio problema è che quando provo ad aggiungere un attributo a un'entità con il tipo NSBooleanAttributeType, diventa un po 'buggato. Quando aggiungo al mio file di intestazione sottoclasse NSManagedObject (nel tutorial, che sarebbe Run.h) comeQual è il tipo per gli attributi booleani nelle entità Core Data?

@property (retain) BOOL *booleanProperty; 

compilazione fallisce, dicendo error: property 'booleanProperty' with 'retain' attribute must be of object type.

Sembra che alcuni posti a Cocoa utilizzano NSNumber oggetti per rappresentare booleani, così ho provato a installare a

@property (retain) NSNumber *booleanProperty; 

invece. Tuttavia, questa evoca i seguenti errori di runtime:

*** -[NSAttributeDescription _setManagedObjectModel:]: unrecognized selector sent to instance 0x101b470 
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSAttributeDescription _setManagedObjectModel:]: unrecognized selector sent to instance 0x101b470' 

Uso GDB, sono in grado di rintracciare questo ritorno alla linea nel mio codice di origine in cui aggiungo la mia entità al modello oggetto gestito:

[DVManagedObjectModel setEntities:[NSArray arrayWithObjects:myEntityWithABooleanAttribute, myOtherEntity]]; 

Quindi la mia domanda è questa: che tipo dovrei impostare booleanProperty nella mia intestazione della classe personalizzata?

risposta

18

Prova:

@property (nonatomic) BOOL booleanProperty; 

Il problema era che è stato utilizzato il conservano nella definizione di proprietà. Per questo è necessario avere una proprietà per una classe Objective-C (dovrebbe essere in grado di capire il metodo 'retain'). BOOL non è una classe ma un alias per il char firmato.

+0

anche vale la pena sottolineare che è "BOOL booleanProperty", senza *. Il * è solo per i puntatori, compresi i puntatori di oggetti. –

+1

Vedere [questa risposta] (http://stackoverflow.com/a/3934284/164989) per una soluzione più appropriata. – opsidao

+0

Questa risposta dovrebbe essere cancellata in quanto non è corretta. –

2

Non so se questo è solo un errore di battitura da parte vostra, ma questo:

[NSArray arrayWithObjects:myEntityWithABooleanAttribute, myOtherEntity] 

è sicuramente sbagliato. L'ultimo parametro di quel metodo dovrebbe sempre essere zero.

+0

Grazie per avermelo fatto notare! Quello era un errore di battitura però. –

6

Uno dei modi migliori per generare corretti di accesso nella sottoclasse NSManagedObject è quello di far apparire il menu contestuale su un attributo o una proprietà nel strumento di modellazione dei dati e scegliere uno dei seguenti comandi:

  • Metodo Copy dichiarazioni da Appunti
  • Metodo Copy implementazioni negli Appunti
  • Copy Obj-C dichiarazioni 2.0 Metodo negli Appunti
  • Copy Obj-C Implementazioni 2.0 Metodo negli Appunti
3

Un attributo di tipo Booleano in un oggetto NSManagedObject è di tipo NSCFBoolean. Questa è una sottoclasse privata di NSNumber.

18

Non suggerirei il metodo suggerito da Diederik Hoogenboom (ho ricevuto un errore anche se il mio attributo dei dati di base era impostato come booleano).

Vale la pena sottolineare che, anche se questa linea di lavoro per un oggetto personalizzato, non funzionerà per una sottoclasse di NSManagedObject:

@property (nonatomic) BOOL booleanProperty; 

La tua struttura deve essere impostato come questo:

@property (nonatomic, retain) NSNumber *booleanProperty; 

quando copio le dichiarazioni di metodo per un tipo booleano (con la tecnica suggerita da Jim Correia), il getter e setter vengono digitati come:

NSNumber:-(NSNumber *)booleanProperty; 
-(void)setBooleanProperty:(NSNumber *)value; 

... questo è ciò che una proprietà booleana nei dati di base è impostato come, ed è necessario per convalidare la vostra proprietà con qualcosa di simile:

-(BOOL)validateBooleanProperty:(NSNumber **)toValidate error:(NSError **)outError 
{ 
    int toVal = [*toValidate intValue]; 

    if ((toVal < 0) || (toVal > 1)) 
    { 
     NSString *errorString = NSLocalizedStringFromTable(@"Boolean Property", @"TheObject", @"validation: not YES or NO"); 
     NSDictionary *userInfoDict = [NSDictionary dictionaryWithObject:errorString forKey:NSLocalizedDescriptionKey]; 

     NSError *error = [[[NSError alloc] initWithDomain:NSCocoaErrorDomain code:-1 userInfo:userInfoDict] autorelease]; 
     *outError = error; 
     return NO; 
    } 
    return YES; 
}//END 

... ricordarsi di includere la dichiarazione validateBooleanProperty nel file di intestazione. I metodi setter e getter memorizzano e recuperano la proprietà usando - (id) primitiveValueForKey: (NSString *).

Infine, è necessario chiamare esplicitamente il metodo validate da qualsiasi vista del regolatore/app delegato si sta impostando l'oggetto da:

NSNumber *boolProp = [[[NSNumber alloc] initWithInt :0] autorelease]; 
    NSError *valError = nil;   
    if ([TheObject validateBooleanProperty:&boolProp error:&valError] == YES) 
    { 
     [TheObject setBooleanProperty :boolProp]; 
    }  
1

Usa NSNumber. Non c'è bool nel framework CoreData.

4

Lascia che Xcode 4.0 decida per te. In Xcode: selezionare un'entità dalla vista file * .xcdatamodel.
Seleziona editor> Crea sottoclasse NSMagedObject ... Xcode dichiara gli oggetti booleani come tipo NSNumber.

Modifica: Sono curioso di sapere quale sia la motivazione per mitigare xcdatamodel? Chiunque?

15

Nell'intestazione,

@property (nonatomic, retain) NSNumber *booleanProperty; 

Nell'implementazione,

@dynamic booleanProperty; 

Per impostare a true ...

self.booleanProperty = [NSNumber numberWithBool:YES]; 

per impostarla su false ...

self.booleanProperty = [NSNumber numberWithBool:NO]; 

di confrontarla con un vero e proprio booleano letterale: ...

self.booleanProperty.boolValue == YES; 

di confrontarla con un letterale falso booleano: ...

self.booleanProperty.boolValue == NO; 

Per maggiori informazioni: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/nsnumber_Class/Reference/Reference.html#//apple_ref/occ/clm/NSNumber/numberWithBool:

+1

Oppure utilizzare la scorciatoia per l'assegnazione, self.booleanProperty = @ (NO); – pojo

+0

Esattamente quello di cui avevo bisogno. Grazie per aver fatto tutto il possibile. (Y) –

Problemi correlati