Objective-C 中 NSArray 的子类

2024-01-23

我需要一个类,它具有 NSArray 的所有方法,其行为方式相同,但修改了 2 个方法。

我想在我的自定义类中重写这两个方法:

1)countByEnumerateWithState:对象:计数:

2)对象索引:

经过几个小时的研究,我没有找到任何合理的方法来做到这一点,因为:

  • 我不想使用类别,因为并非所有 NSArray 实例都应该具有修改后的行为。 (另外这会引发警告)

  • 我不想重写所有初始化程序加上所有 arrayWith... 方法 + 原始方法 + 实现我自己的存储(因为这个功能已经在 Cocoa 中实现了,对吗?为什么我要重新实现 a 的所有功能?已经存在的类?)

  • 如果我让我的自定义类继承 NSObject 并使用 NSArray 作为 ivar 中的存储,那么在 Xcode 中编程时所有 NSArray 的方法都不可用(即使我可以将它们转发到 NSArray ivar)

  • 我通过使用 method_setImplementation(...) 成功地按需覆盖了方法实现,但仍然无法找到一种在运行时动态创建类的方法,然后该类将具有我提到的 2 个方法的自定义实现。

期待您的想法!谢谢


Mantra:如果某件事很困难(或者看起来需要比必要的更多的代码),那么您的设计很可能违背了 iOS / OS X 框架的设计原则。重新审视您的设计可能会产生更好的解决方案。


为了回答最初的问题,如果你想子类化 NSArray (或 NSMutableArray),你需要实现原始方法,不多也不少。

原始方法是在@interface类本身的。 IE。:

@interface NSArray : NSObject
- (NSUInteger)count;
- (id)objectAtIndex:(NSUInteger)index;
@end

对于 NSMutableArray:

@interface NSMutableArray : NSArray
- (void)addObject:(id)anObject;
- (void)insertObject:(id)anObject atIndex:(NSUInteger)index;
- (void)removeLastObject;
- (void)removeObjectAtIndex:(NSUInteger)index;
- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject;
@end

如果你继承 NSMutableArray 并实现上述 7 个方法(这两个方法也来自 NSArray),你将拥有一个与所有使用可变数组的 API 兼容的 NSMutableArray 子类(假设你的方法正确实现)。

这是因为类簇的设计方式。公共类是抽象的;永远不会直接实例化。它们提供了一个原始接口,其中包含类的核心功能,然后是根据原语实现的所有其他非原始 API(除了初始化程序,见下文)的具体实现。然后,具体的私有子类会覆盖所有原语和一些非原语,以为特定配置提供最佳行为。

我想要为我正在开发的库提供一个 NSArray 实例,并且我 希望它对我的图书馆的用户透明地工作。 IE。 对于他们来说,使用普通的 NSArray 和 我将提供的修改后的课程。 IE。这是一个存储问题, 最终用户不应该关心的内容和界面 应与 NSArray 保持相同 - 因此丢失所有 init 方法 那时确实不是一个选择。

初始化方法are not原始接口的一部分NSArray。您添加的要求超出了“使类与NSArray / NSMutableArray“正如文档中所定义的。这没有什么问题,只是指出来。

之所以会出现这种情况,是因为极少对集合类进行子类化以提供您所描述的业务逻辑类型。集合的行为非常通用,而条件化集合行为的业务逻辑将在管理整个模型层对象图的类中完成。

如果你真的想这样做,请提供任何实现init*您想要的方法,根据需要调用包装的通用实例。初始化程序的实现并没有什么特别之处,以至于您这样做会损失很多。

也无需全部实施。实现一两个并在其余的上@抛出一个描述性异常。

如果您确实决定转发接受 var-args 的那些,则不能直接转发,因为没有 va_list 接受方法。相反,您需要将参数 va_list 转换为语言数组(即id[] foo = malloc(... * sizeof(id));)并将其传递给initWithObjects:count:.

其他一些评论:

  • 您正在做的事情 [在子类中提供完整的 NS*Array 接口] 似乎很困难,因为它不是常见的模式,并且框架设计者认为不需要创建一个设计来支持它。原始集合级别的自定义行为几乎总是在对象图中的更高级别上更好地实现。Almost always.

  • method_setImplementation() 和动态类创建在学术上很有趣,但几乎从来都不是解决方案。显然,破坏 NSArray 或 NSMutableArray 类(或具体实现类)将会破坏依赖标准行为的其余框架。除此之外,它是一种动态 OO 组合模式,并不真正打算在 Objective-C 中使用;维护起来会很痛苦。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Objective-C 中 NSArray 的子类 的相关文章

随机推荐