有没有什么办法猴子补丁或调酒一个NSArray(或其他类簇)?(Is there any way t

2019-07-30 17:41发布

今天我工作中,我想“别名”为所有实例的替代方法的项目NSArray ,并没有想到它会与一些太困难了老式的方法交叉混合。

我爆发了JRSwizzle和...

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

需要明确的是,我这个配对上的相应类别NSArray ,称为实例方法objectAtIndex_accordingToMe:

不过,我刚刚同老物件,以相同的旧索引 。 叹。 最后,我想通了,尽管没有抛出任何错误-我不会取得这些成果是由于事实NSArray是一个类群集

我想我的问题更多的是不愿意接受,“这”确实是在路上试图重写结束NSArray方法。 我的意思是,来吧,这是NSArray 。人们必须与它周围淤泥想,不是吗? 有人会认为 ,苹果公司的基础类将是swizzlers的主要目标,无处不在!

那么,有没有办法改变,别名, 猴子补丁 ,覆盖或以其他方式与...一个NSArray自己的方式,等等。(没有子)?

Answer 1:

想必你有一个特定的阵列您希望此行为其。 你可以得到该实例的类对象,不管它是什么,那调酒很容易:

[[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];


Answer 2:

这不仅仅是因为它是一类集群。 NSArray是拨打免费电话桥接CFArray ,你不能拌和核心基础。 因此,这是不太可能在一般的工作。

但是,你有什么解决? 如果你想添加一个新方法,使用类别。 他们对类集群的工作就好了。 修改对NSArray的一些内置的行为似乎是一个灾难(娱乐性它可能是作为一个练习)。

去之前太远 ,你可能要至少看一看CFArray.c并了解了一些潜在的东西实现。


编辑:虽然我绝不会做这种在生产代码,你可以通过劫持单个阵列的情况下,与ISA-交叉混合得到一些你想要的东西。 见ISASwizzle的一些示例代码。 该代码的解释是在第20章的iOS:PTL 。 搜索出“ISA调酒”,你应该找到更在网络上。 这是国际志愿者组织是如何实现的。 但随着NSArray的......哇,那得是脆弱的。



文章来源: Is there any way to monkey-patch or swizzle an NSArray (or other Class Cluster)?