Domanda

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 motivo per cui il seguente non si traduca in un errore di compilazione o avviso:

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.

La cosa che mi ha lasciato perplesso è il motivo per cui 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à un NSNumber * in questo caso particolare.

Perché non questo risultato in un avviso del compilatore sulla falsariga di "id potrebbero non rispondere ai '-integerValue'"?

È stato utile?

Soluzione

Spero ho capito bene: Questo perché id è “speciale”. Gli oggetti del tipo id possono essere inviati qualsiasi messaggio che si desidera, non v'è alcun controllo fatto dal compilatore e tutto sarà controllato in fase di esecuzione. O, in altre parole, il tipo di id è la parte “dinamica tipizzazione” 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 le stringhe “strettamente” come NSStrings, perché si ottiene la comodità di fase di compilazione controllo di tipo statico e solo ricorrere alla tipizzazione dinamica, dove quello statico sarebbe ottenere nel modo, come nella situazione valueForKey.

Altri suggerimenti

Il tempo è passato e noi abbiamo una migliore inferenza di tipo ora grazie al __auto_type disponibile dal Xcode 8. Così ora si può fare

#define let __auto_type const
#define var __auto_type

let a = @[@"pew pew"];
var b = 2;
b = a; //compiler warning "Incompatible pointer to integer conversion assigning to 'int' from 'NSArray *__strong const'"

molto di più

In effetti, mi è piaciuto tanto che ho fatto questo come un baccello per convenienza.

pod 'SwiftyObjC'
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top