【问题标题】:C# "as" keyword in Objective-CObjective-C 中的 C#“as”关键字
【发布时间】: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


    【解决方案1】:

    在 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]];
    

    【讨论】:

    • 请注意,Objective-C 中的这种元编程通常是一种“代码味道”,表明您的架构远远超出语言和框架的规范。
    • @bbum,澄清一下,您并不是反对使用类别,而是需要 C# 中的 as 功能?
    • 类别通常也很糟糕。它们通常是导致糟糕设计的拐杖。
    【解决方案2】:

    不,不存在这样的关键字,但您可以使用宏来模拟这样的行为。

    #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 有副作用,这可能会导致性能问题或其他问题。

    【讨论】:

    • 我应该如何将不使用它的建议移到顶部:)
    【解决方案3】:

    类型转换(只是 C):

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

    注意:你可以用这个射自己的脚,小心。

    【讨论】:

    • 没有投反对票,但这不是一回事。 as 检查 RTTI 以验证类型兼容性。 c# 也有 c 风格的转换,所以这不是真正的要求。
    • 我真的很困惑为什么这是投票,这个答案是不正确的。
    • @H2CO3,我认为您不了解as 关键字。如果要转换的对象不属于适当的类,as 关键字将返回 nil。使用您的示例,我可以将NSNumber 转换为NSString
    • @JasonWhitehorn 检查我回复 Donnie 的链接。
    猜你喜欢
    • 2010-12-31
    • 1970-01-01
    • 1970-01-01
    • 2012-08-18
    • 2011-03-10
    • 2018-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多