Objective-C中的轻量级泛型

7
我正在尝试使用轻量级通用模板实现堆栈类。但是代码无法编译,因为Xcode找不到“ObjectType”的定义。
@implementation Stack
- (ObjectType)popObject     !!!!!!!!!Expected a type
{
    return self.allObjects.firstObject;
}
@end

这很奇怪,因为标题声明并不会生成任何错误。

@interface Stack<__covariant ObjectType> : NSObject
- (ObjectType)popObject;
@property (nonatomic, readonly) NSArray<ObjectType> *allObjects;
@end

我可以通过将ObjectType更改为id使其工作。 有更好的方法来解决这个错误吗?

2个回答

18

Objective-C泛型确实很轻量级,它们的添加是为了改善与Swift的互操作性,而不是使Objective-C代码更安全。类似于可空性,将泛型视为一种注释您接口的方式而不是更改实现的原因。

在实现中将ObjectType更改为id是前进的最佳方式。

进一步阅读:关于Objective C Generics的文章。如果您想了解__covariant,请阅读那篇文章中Bob的评论。


没错,为了更加清楚明了:泛型在实现中根本不存在,所以不必费心去修改你的 .m(m) 文件。 - DrMickeyLauer
文章链接已失效。 - Greg
用archive.org替换了链接。 - Douglas Hill

2

只是一个假设,但如果将ObjectType替换为id有效,则可能您使用的不是指针类型?

我的意思是,如果您有@interface ObjectType,那么在Stack中,它应该在<...>括号和方法返回类型中都是ObjectType*

如果这不是问题,对于误导您,我感到抱歉


NSArray.h 使用以下声明:- (ObjectType)objectAtIndex:(NSUInteger)index;。然而,苹果并没有提供实现文件。 - Hai Feng Kao
这是因为ObjectType在这里不仅可以是指向ObjC对象的指针。它可以是id,一些GCD对象或Core Foundation对象。 - Sergii Martynenko Jr
@SergiiMartynenkoJr: 没错,所以如果ObjectTypeNSString *,那么使用ObjectType *会扩展为NSString **,这不是预期的结果。ObjectType似乎是正确的选择。 - Jesper
看起来好像有误解。让我们降低抽象层次。假设我们有一个 @interface Some。那么,在 Stack 中,我们应该有:`@interface Stack<__covariant Some*> - (Some*)popObject; @property NSArray *allObjects; @end` - Sergii Martynenko Jr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接