使用新的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
。
建议非常感谢! :)
答案 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>
声明它的方式意味着MyHelperClass
对T
不变,因此将MyHelperClass<instancetype> *
用作{a}}是不安全的返回类型也不作为参数类型。
当然,所有这一切都没有实际意义,因为语言现在不允许MyHelperClass<instancetype> *
之类的东西;我只是指出允许它采取什么措施。