gpt4 book ai didi

objective-c - Objective-C 中的 NSArray 子类

转载 作者:可可西里 更新时间:2023-11-01 04:23:52 25 4
gpt4 key购买 nike

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

我想在我的自定义类中覆盖这两个方法:

1) countByEnumeratingWithState:objects:count:

2) objectAtIndex:

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

  • 我不想使用类别,因为并非所有 NSArray 实例都应该具有修改后的行为。 (加上抛出警告)

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

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

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

期待您的想法!谢谢

最佳答案

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


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

原始方法是在类本身的@interface 中声明的方法。即:

@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 子类——假设您的方法已正确实现。

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

I want to have an NSArray instance for a library I'm working on and I want to have it working transparently for the users of my library. Ie. for them should be no difference between using a normal NSArray and the modified class I'll be providing. Ie. it's a storage concern, which the end users should not be concerned with and the interface should remain the same as NSArray - therefore loosing all init methods is not really an option at that point.

初始化方法不是 NSArray 原始接口(interface)的一部分。您在文档中定义的“使类与 NSArray/NSMutableArray 兼容”之外添加了一项要求。这没什么不对,只是指出来。

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

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

也不需要实现所有这些。实现一两个,并对其余部分 @throw 一个描述性异常。

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

一些其他评论:

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

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

关于objective-c - Objective-C 中的 NSArray 子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13920451/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com