【发布时间】:2012-12-01 20:58:22
【问题描述】:
Objective-C 中是否有类似 C# (as) 的 cast 关键字:
Foo bar = new Foo();
Foo tmp = bar as Foo;
这在 Objective-C 中可行吗?
【问题讨论】:
标签: objective-c xcode oop casting
Objective-C 中是否有类似 C# (as) 的 cast 关键字:
Foo bar = new Foo();
Foo tmp = bar as Foo;
这在 Objective-C 中可行吗?
【问题讨论】:
标签: objective-c xcode oop casting
在 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]];
【讨论】:
as 功能?
不,不存在这样的关键字,但您可以使用宏来模拟这样的行为。
#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>
bar as Foo: (null)
我建议直接检查isKindOfClass:,而不是使用名称不佳的宏,例如AS。此外,如果宏的第一个参数是表达式,例如 ([foo anotherFoo]),它将被计算两次。如果anotherFoo 有副作用,这可能会导致性能问题或其他问题。
【讨论】:
类型转换(只是 C):
Foo *foo = [[Foo alloc] init];
Bar *bar = (Bar *)foo;
注意:你可以用这个射自己的脚,小心。
【讨论】:
as 检查 RTTI 以验证类型兼容性。 c# 也有 c 风格的转换,所以这不是真正的要求。
as 关键字。如果要转换的对象不属于适当的类,as 关键字将返回 nil。使用您的示例,我可以将NSNumber 转换为NSString。