2012-12-13 116 views

回答

4

Objective-C中沒有直接等效於as。有常規型鑄造(C型)。

如果你想檢查物體的類型,一定要打電話isKindOfClass:

要寫入相當於:

Foo bar = new Foo(); 
Foo tmp = bar as Foo; 

你會寫:

Foo *bar = [Foo new]; 
Foo *tmp = ([bar isKindOfClass:[Foo class]]) ? (Foo *)bar : nil; 

你總是可以把這件事寫成像類別:

@implementation NSObject (TypeSafeCasting) 

- (id) asClass:(Class)aClass{ 
    return ([self isKindOfClass:aClass]) ? self : nil; 
} 

@end 

,那麼你可以這樣寫:

Foo *bar = [Foo new]; 
Foo *tmp = [bar asClass:[Foo class]]; 
+1

+1我喜歡這個類別,它會更好。 – Joe

+2

請注意,Objective-C中的這種元編程通常是一種「代碼異味」,表明您的架構遠遠超出了語言和框架的規範。 – bbum

+0

@bbum,只是爲了澄清,你不是反對使用類別,而是需要C#中的'as'功能? –

0

鑄字(這只是C):

Foo *foo = [[Foo alloc] init]; 
Bar *bar = (Bar *)foo; 

注意:您可以拍攝自己與這個腳,要小心。

+0

Downvoter:reason? – 2012-12-13 21:36:28

+0

沒有downvote,但這不是一回事。 'as as'檢查RTTI以驗證類型兼容性。 c#也有C風格的轉換,所以這並不是真正的要求。 – Donnie

+0

@Donnie [我也知道。](http://stackoverflow.com/questions/10557756/objective-c-dynamic-cast/10557838#10557838) – 2012-12-13 21:55:31

0

只需使用鑄件C提供了(這是我在C#中使用,以及語法)

id myObj = [[Obj alloc] init]; 
    ObjParentClass * ptr = (ObjParentClass *)myObj; 

當然,在C#中你沒有指針,但我總是做我的鑄件與(TypeImCastingTo)instance

+0

如果你將'myObj'定義爲'id',你甚至不需要投射。 – 2012-12-13 21:41:34

+0

@ H2CO3是真的,那是一個毫無意義的例子。現在好多了。 – evanmcdonnal

1

不,不存在這樣的關鍵字,但可以用宏模擬這種行爲。

#define AS(x,y) ([(x) isKindOfClass:[y class]] ? (y*)(x) : nil) 

@interface Foo : NSObject 
@end 
@implementation Foo 
@end 

int main(int argc, char *argv[]) 
{ 
    @autoreleasepool { 

     Foo *bar = [[Foo alloc] init]; 
     Foo *tmp = AS(bar, Foo); 

     NSLog(@"bar as Foo: %@", tmp); 

     bar = [NSArray array]; 
     tmp = AS(bar, Foo); 
     NSLog(@"bar as Foo: %@", tmp); 
    } 
} 

輸出:

酒吧爲Foo:<Foo: 0x682f2d0>
酒吧爲Foo:(空)

我建議只檢查isKindOfClass:,而不是直接使用一個名爲不佳的宏像AS。另外,如果宏的第一個參數是一個表達式,例如([foo anotherFoo]),它將被評估兩次。這可能會導致性能問題或其他問題,如果anotherFoo有副作用。

+0

我應該如何移動建議,不要將它用於頂層:) – Joe