2010-01-16 17 views
8

Va bene, ho la sensazione che si guys'll in grado di rilevare rapidamente perché sono così confuso su questo, ma ho una domanda sul perché di seguito non si traduca in un compilatore errore o avviso:Objective-C Type Inference

NSString * intValue = [ NSString stringWithFormat:@"int = %i", [ [ self.selectedObject valueForKey:name ] integerValue ] ]; 

selectedObject è un NSObject e name sembra essere il nome di un @property di tipo int.

Quello che mi lascia perplesso è il motivo per il compilatore è perfettamente disposto a ritenere che il risultato ritorno di [ self.selectedObject valueForKey:name ] è di tipo NSNumber * (senza typecasting) al fine di catena il messaggio con una chiamata a integerValue.

Ovviamente, KVC avvolge non oggetto di tipo "numero" in NSNumber, ma non c'è modo per il compilatore a sapere che -valueForKey: restituirà una NSNumber * in questo caso particolare.

Perché questo non risulta in un avviso del compilatore lungo le linee di "id potrebbe non rispondere a '-integerValue'"?

risposta

10

spero ho capito bene: Questo perché id è “speciale”. Gli oggetti del tipo id possono essere inviati a qualsiasi messaggio, non ci sono controlli effettuati dal compilatore e tutto verrà controllato in runtime. O, in altre parole, il tipo di id è la parte “tipizzazione dinamica” di Objective-C, mentre tutti gli altri tipi (come NSObject) sono la parte “tipizzazione statica”.

In questo modo è possibile scegliere dove si desidera utilizzare tipizzazione statica, e dove si desidera utilizzare la tipizzazione dinamica. E 'perfettamente legale per fare qualcosa di simile:

id str1 = @"Hello"; 
id str2 = [str1 stringByAppendingString:@", world"]; 

Ma di solito si digita la stringa “strettamente” come NSString s, perché si ottiene la comodità di fase di compilazione controllo di tipo statico, e ricorrere solo per la tipizzazione dinamica in cui quello statico si metterebbe in mezzo, come nella situazione valueForKey.

+0

Grazie! Avevo la sensazione che avesse a che fare con 'id' come tipo privilegiato in Objective-C. :) La mia tendenza è di scrivere SEMPRE le cose quando possibile, quindi suppongo di non aver mai incontrato questo comportamento apparentemente strano. Indovinate che rende 'id' sia potente che pericoloso. Mi chiedo se sia meglio digitare per dare al compilatore un contesto quando si ha a che fare con 'id', o se è perfettamente corretto lasciarlo fuori se si è sicuri di cosa diventerà' id' (come nel mio esempio) . – LucasTizma

+0

La regola del pollice è: “tipizzazione statica per quanto possibile, la tipizzazione dinamica quando necessario” (. È possibile che Google per avere ulteriori informazioni) In questo caso non mi typecast, sarebbe solo rendere l'espressione più difficile da leggere. A volte devi digitare per aiutare il compilatore a scegliere il metodo giusto - vedi http://stackoverflow.com/questions/1113270. – zoul

+0

Grazie per il link. Ho riscontrato alcuni piccoli bug sgradevoli a causa della denominazione dei metodi che si verifica in "conflitto" con i nomi dei metodi SDK esistenti. Pensavo che il compilatore stesse impazzendo per me. :) E sì, sono totalmente un sostenitore della filosofia "Static Typing Where Possible, Dynamic Typing When Needed". Ora, se solo Objective-C aggiungesse il supporto per le raccolte tipizzate ... Apparentemente molto spesso, so che cosa le mie collezioni stanno per archiviare. – LucasTizma