我有一個類A
與財產NSString *name
。如果有一個NSArray
並將許多A
對象添加到此數組中,每次檢索對象時都需要進行強制轉換?即NSArray的對象和鑄造
NSString* n = (NSString*)[arr objectAtIndex:1];
還是有另一種方式來做到這一點有點像在Java中,你必須ArrayList<A> arr
?
我有一個類A
與財產NSString *name
。如果有一個NSArray
並將許多A
對象添加到此數組中,每次檢索對象時都需要進行強制轉換?即NSArray的對象和鑄造
NSString* n = (NSString*)[arr objectAtIndex:1];
還是有另一種方式來做到這一點有點像在Java中,你必須ArrayList<A> arr
?
NSArray
不存儲關於其中包含的對象類型的信息。如果你確切地知道類型的數組中的對象,你可以進行一次造型,無論是或明或暗地:
NSString *n = [arr objectAtIndex:1]; // implicit type conversion (coercion) from id to NSString*
NSString *n = (NSString *)[arr objectAtIndex:1]; // explicit cast
有一個在隱式和顯式轉換之間的運行成本沒有什麼區別,它只是一個風格問題。如果你的類型錯誤,那麼很可能會發生的是你會遇到令人生畏的unrecognized selector sent to instance 0x12345678
異常。
如果您有不同類型的對象的異構陣列,您需要使用isKindOfClass:
方法來測試對象的類:
id obj = [arr objectAtIndex:1];
if ([obj isKindOfClass:[NSString class] ])
{
// It's an NSString, do something with it...
NSString *str = obj;
...
}
這是做到這一點的方法。無論如何,你可以實際執行上述操作,而無需強制返回,因爲你正在將它讀入NSString。
這是這樣的:
NSMutableArray *objectsArray = [[NSMutableArray alloc] init];
A *a= [[A alloc] init];
[objectsArray addObject:a];
[a release];
您不必擔心proprety型
NSArray
的objectAtIndex:
返回id
類型的變量。這大致相當於在Java中返回一個Object
-「我們不能保證太多關於這個變量的類型。」然而,在Objective-C中,您可以發送消息到id
變量,而無需編譯器抱怨。所以,因爲你知道該數組只包含A
個實例,所以你最好把它發送給name
消息。例如,下面將編譯沒有警告:
NSString *name = [[array objectAtIndex:0] name];
但是,如果你想使用點符號(如[array objectAtIndex:0].name
),你需要的id
強制轉換爲A *
如下所示:
NSString *name = ((A *)[array objectAtIndex:0]).name;
perfect ..只是我正在尋找的信息 – Tim
值得注意的是,在運行時無法區分NSStrings和NSMutableStrings,它們都對'isKindOfClass:[NSMutableString class]'回答YES。 – Chuck
@Chuck:我不知道。怎麼來的? –
@Chuck:我注意到NSString也向'[myNSString respondsToSelector:@「appendFormat:];'ISTM返回YES,可變和不可變字符串都是由__NSCFString實現的,並且有一些內部標誌,告訴它它是否可變或不可變。如果你調用'[myNSString appendFormat:@「world」];'你得到一個異常,但不是一個表明它不響應選擇器的異常。顯然'appendFormat:'檢查不可變標誌,如果它被設置,引發一個異常,可變和不可變的字符串實際上是同一個類,'__NSCFString'。 –