- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我需要一个类,它有 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/
我遵循了一本名为“Sitepoint Full Stack Javascript with MEAN”的书中的教程,我刚刚完成了第 6 章,应该已经创建了一个带有“数据库”的“服务器”。数据库只不过是
在 Jquery 中,我创建两个数组,一个嵌入另一个数组,就像这样...... arrayOne = [{name:'a',value:1}, {name:'b',value:2}] var arra
这个问题在这里已经有了答案: What is the explanation for these bizarre JavaScript behaviours mentioned in the 'Wa
我被放在别人的代码上,有一个类用作其他组件的基础。当我尝试 ng serve --aot(或 build --prod)时,我得到以下信息。 @Component({ ...,
我正在测试一些代码,并使用数据创建了一个 json 文件。 问题是我在警报中收到“[object Object],[object Object]”。没有数据。 我做错了什么? 这是代码:
我想打印 [object Object],[object Object] 以明智地 "[[{ 'x': '1', 'y': '0' }, { 'x': '2', 'y': '1' }]]"; 在 ja
我有一个功能 View ,我正在尝试以特殊格式的方式输出。但我无法让列表功能正常工作。 我得到的唯一返回是[object Object][object Object] [object Object]
在使用优秀的 Sim.js 和 Three.js 库处理 WebGL 项目时,我偶然发现了下一个问题: 一路走来,它使用了 THREE.Ray 的下一个构造函数: var ray = new THRE
我正在使用 Material UI 进行多重选择。这是我的代码。 {listStates.map(col => (
我的代码使用ajax: $("#keyword").keyup(function() { var keyword = $("#keyword").val(); if (keyword.
我遇到了下一个错误,无法理解如何解决它。 Can't resolve all parameters for AuthenticationService: ([object Object], ?, [o
我正在尝试创建一个显示动态复选框的表单,至少应选中其中一个才能继续。我还需要获取一组选中的复选框。 这是组件的代码: import { Component, OnInit } from '@angul
我正在开发 NodeJs 应用程序,它是博客应用程序。我使用了快速验证器,我尝试在 UI 端使用快速闪存消息将帖子保存在数据库中之前使用闪存消息验证数据,我成功地将数据保存在数据库中,但在提交表单后消
我知道有些人问了同样的问题并得到了解答。我已经查看了所有这些,但仍然无法解决我的问题。我有一个 jquery snipet,它将值发送到处理程序,处理程序处理来自 JS 的值并将数据作为 JSON 数
我继承了一个非常草率的项目,我的任务是解释为什么它不好。我注意到他们在整个代码中都进行了这样的比较 (IQueryable).FirstOrDefault(x => x.Facility == fac
我只是在删除数组中的对象时偶然发现了这一点。 代码如下: friends = []; friends.push( { a: 'Nexus', b: 'Muffi
这两个代码片段有什么区别: object = nil; [object release] 对比 [object release]; object = nil; 哪个是最佳实践? 最佳答案 object
我应该为其他人将从中继承的第一个父对象传递哪个参数,哪个参数更有效 Object.create(Object.prototype) Object.create(Object) Object.creat
我在不同的对象上安排不同的选择器 [self performSelector:@selector(doSmth) withObject:objectA afterDelay:1]; [self per
NSLog(@"%p", &object); 和 NSLog(@"%p", object); 有什么区别? 两者似乎都打印出一个内存地址,但我不确定哪个是对象的实际内存地址。 最佳答案 这就是我喜欢的
我是一名优秀的程序员,十分优秀!