4

今天我正在做一个项目,我想为 的所有实例“别名”一种替代方法,并且认为使用一些好的老式方法调配NSArray不会太困难。

我爆发了JRSwizzle,然后……</p>

[NSArray jr_swizzleMethod:@selector(objectAtIndex:) withMethod:@selector(objectAtIndex_accordingToMe:) error:nil];

为了清楚起见,我将它与适当的类别 on 配对NSArray,一个名为 的实例方法objectAtIndex_accordingToMe:

但是,我只是在同一个旧索引处得到同一个旧对象。叹。最终,我发现尽管没有抛出任何错误——我不会实现这些结果,因为它NSArray是一个类集群

NSArray我想我的问题更多是不愿意接受“这”真的是试图覆盖方法的尽头。我的意思是,来吧这是NSArray..人们一定想搞砸它,不是吗?人们会认为Apple 的基础课程将成为各地调酒师的主要目标!

那么,有没有办法改变、别名、monkey-patch、覆盖或以其他方式使用...... NSArray 等(没有子类化)?

4

2 回答 2

4

这不仅仅是一个类集群。NSArray已免费桥接到CFArray,并且您无法调配 Core Foundation。因此,这通常不太可能起作用。

但是你想解决什么问题?如果要添加新方法,请使用类别。他们在类集群上工作得很好。修改 NSArray 上某些内置的行为似乎是灾难的秘诀(有趣,因为它可能是一个练习)。

走得太远之前,您可能至少想看看CFArray.c并了解一些底层内容是如何实现的。


编辑:虽然我永远不会在生产代码中这样做,但您可以通过使用 ISA-swizzling 劫持单个数组实例来获得一些您想要的东西。有关一些示例代码,请参阅ISAwizzle。代码解释在iOS:PTL的第 20 章。搜索“isa swizzle”,您应该可以在网上找到更多信息。这就是 KVO 的实现方式。但是使用 NSArray ......哇,那一定很脆弱。

于 2012-08-01T02:06:56.573 回答
3

大概你有一个你想要这种行为的特定数组。无论它是什么,您都可以获取该实例的类对象,并且可以很容易地进行调整:

[[myArray class] jr_swizzleMethod:@selector(objectAtIndex:) withMethod:@selector(objectAtIndex_accordingToMe:) error:nil];

也只有几个具体的子类NSArray

NSArray * trees = [NSArray array];
NSArray * birds = [NSArray arrayWithObjects:@"Albatross", @"Budgerigar", @"Cardinal", nil];
NSMutableArray * dogs = [NSMutableArray arrayWithObjects:@"Airedale", @"Beagle", @"Collie", nil];

NSLog(@"%@ %@ %@", [trees class], [birds class], [dogs class]);

我们得到__NSArrayI了前两个和__NSArrayM第三个,所以可能(这是非常脆弱的)您可以使用运行时函数按名称获取类对象:

[objc_getClass("__NSArrayI") jr_swizzleMethod:@selector(objectAtIndex:) withMethod:@selector(objectAtIndex_accordingToMe:) error:nil];
于 2012-08-01T02:06:13.163 回答