2013-01-03 15 views
5

Ho iniziato a programmare un'app per iPhone utilizzando CoreData e cercando di rendere il mio codice base il più possibile manutenibile. Perciò io vorrei evitare stringhe hard-coded come ad esempio:Nome attributo NSPredicate CoreData

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@", aName]; 

Invece mi piacerebbe essere in grado di scrivere qualcosa di simile:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", Person.name, aName]; 

In questo modo avrei avuto il compilatore per verificare se name è una proprietà dell'entità Person ed evitare errori di ortografia.

Con questo codice se sto ottenendo il seguente errore in fase di compilazione: proprietà name non trovato in oggetto di tipo Person

Person essere di tipo NSManagedObject e automaticamente generato da Xcode dal mio MyApp.xcdatamodeld.

name è un semplice attributo di stringa del soggetto Person

Googled e SOed un bel po 'già una risposta a questo problema specifico. Ho anche provato a utilizzare property_getName e NSPropertyDescription con poca fortuna finora.

Grazie in anticipo per l'aiuto,

Joss.

+0

Non funziona in questo modo, si dovrebbe comunque fornire '@" nome "' all'argomento '@ K'. – Joe

risposta

4

Se si utilizza Mogenerator, per eccellente suggerimento di Kendall, nelle classi auto-generate otterrete tre struct s dichiarati nell'intestazione - EntityNameAttributes, EntityNameRelationships, e EntityNameFetchedProperties. Ad esempio, se la tua entità è denominata Person e disponeva di un attributo name, potresti ottenere l'accesso alla chiave utilizzando PersonAttributes.name. Ciò consentirebbe di evitare di avere i nomi delle chiavi hard-coded nel codice dell'applicazione.

+0

Non sapevo che fosse incluso nei modelli predefiniti.Questa è la strada da percorrere per sicuro quindi. Bella risposta! Joss, dovresti accettare questa risposta (fai clic sul segno di spunta a sinistra e la contrassegnerà come accettata). –

+0

@KendallHelmstetterGelner grazie !! –

+0

@CarlVeazey: meravigliosa risposta! Esattamente quello che stavo cercando. Questa è stata la mia prima domanda su SO, davvero felice! – Joss

4

Prima di tutto, Person.name non esiste perché "nome" è una proprietà di un'istanza di persona, non una proprietà di livello di classe.

Non sono sicuro che esista un percorso molto chiaro da un nome di metodo controllato dal compilatore a una stringa. È sempre possibile utilizzare i metodi di livello inferiore per accedere alle firme dei metodi da una classe e ottenere stringhe da essi, ma il punto di partenza è una stringa non controllata (C o ObjC).

In generale l'uso di predicati genera errori se si ottiene il nome errato, quindi qualsiasi test che utilizza un predicato verificherà che il metodo è corretto.

È necessario utilizzare Mogenerator per generare oggetti dati da utilizzare con il modello. In tal caso, è possibile esaminare la modifica dei modelli per aggiungere un metodo chiamato "stringForMethodNamed * Nome *" e includerlo come uno dei parametri nel predicato formattato.

+0

Grazie per la tua risposta completa Kendall! Oggi ho appena sentito parlare di Mogenerator ;-). Immagino sia ora che la guardi. Vorrei poter votare la tua risposta. Sono un noob su SO e non ho abbastanza reputazione. – Joss

+0

Nessun problema, se accetti una risposta otterrai una certa reputazione. –