Objective-C泛型中__typeof self?

时间:2015-10-13 00:09:54

标签: objective-c generics

使用新的Objective-C泛型语法是否可以 - 或者这是怎么回事?

@class MyHelperClass<T>;

@interface NSObject (Extension)
    @property (nonatomic,readonly) MyHelperClass<MYTYPE *> * helper;
@end

问题是:

占位符MYTYPE *的语法是什么 - 它是否存在 - 这使得它可以与NSObject的任何子类一起使用。这意味着,在UIView实例上,helper属性将返回MyHelperClass<UIView *>,而在NSString实例上,它将返回MyHelperClass<NSString *>__typeof self无效,因为未在界面中定义self

建议非常感谢! :)

2 个答案:

答案 0 :(得分:5)

我不认为这是可能的。我能想到的最明显的方法是:

@interface NSObject (Extension)

- (MyHelperClass<instancetype> *)a;

@end

根据clang文档,

  

instancetype是一个上下文关键字,只允许在Objective-C方法的结果类型中使用

这是一个编译器错误,因此,文档应该读取&#34; instancetype只允许作为 Objective-C方法的结果类型。&#34;

我的下一个想法是写一些Swift代码作弊

protocol Test {
  var a: Array<Self> {get}
}

然后将其导入Objective-C文件,以查看预处理器将其转换为Objective-C的功能。遗憾的是,根据documentation here,Swift中的泛型无法从Objective-C - 访问,因为它们不是Objective-C语言的特性!本文档根据修订历史,实际上已经为Swift 2.0更新了。可能它们仍然不受支持,因为即使使用当前可用的泛型,Objective-C类型系统也不像Swift那样具有表现力。

总之,除了我不知道的一些模糊的铿锵声,我认为没有办法做到这一点。

答案 1 :(得分:0)

与其他答案一样,我不认为语言现在允许这种事情,只是因为它似乎是一个很少使用的功能,有许多潜在的并发症。我想指出一些具有这种特性和继承的类型安全问题。

如果MyHelperClass<instancetype> *是方法的返回类型,那么只有MyHelperClass在其类型参数方面是协变的(即,如果它被声明为@class MyHelperClass<__covariant T>),它才是安全的。这是因为如果类Foo具有这样的方法,它也将由任何子类Bar继承。然后当有人在Foo *类型的引用上调用此方法时,他们会期望返回MyHelperClass<Foo *> *,但它可能是MyHelperClass<Bar *> *。它是__covariant意味着MyHelperClass<Bar *> *可以隐式转换为MyHelperClass<Foo *> *

类似地,如果MyHelperClass<instancetype> *是方法的参数类型,那么只有MyHelperClass在其类型参数方面具有逆变性时才会安全(即如果它被声明为@class MyHelperClass<__contravariant T> )。如上所述,当某人在类型为Foo *的引用上调用此方法时,他们可以传入MyHelperClass<Foo *> *,但该方法可能需要MyHelperClass<Bar *> *。它是__contravariant意味着MyHelperClass<Foo *> *可以隐式转换为MyHelperClass<Bar *> *

这也解释了为什么instancetype被允许作为返回类型 - 因为类型对于它自身是协变的。

您使用@class MyHelperClass<T>声明它的方式意味着MyHelperClassT不变,因此将MyHelperClass<instancetype> *用作{a}}是不安全的返回类型也不作为参数类型。

当然,所有这一切都没有实际意义,因为语言现在不允许MyHelperClass<instancetype> *之类的东西;我只是指出允许它采取什么措施。