如何在子类上使用方法swizzle或其他东西

时间:2014-02-09 16:22:25

标签: ios objective-c

我的应用程序中有许多UITableViewController子类。

现在我只需修改它们以在所有情况下添加+1行,并在所有情况下添加一个简单相等的行。

我不想手动修改所有这些,更好的方法似乎是替换UITableViewDataSource方法来修改值,如:

+(void)load {
[[self class] jr_swizzleMethod:@selector(tableView:numberOfRowsInSection:) withMethod:@selector(swizzledTableView:numberOfRowsInSection:) error:nil];
}

- (NSInteger)swizzledTableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self swizzledTableView:tableView numberOfRowsInSection:section] + 1;
}

但是它取代了超类函数,它没有在子类中调用,所以这不起作用。有没有方法可以做我想要的,而无需修改所有子类?

4 个答案:

答案 0 :(得分:2)

您需要专门调配每个子类。您可以通过使用objc_getClassList在运行时内省类层次结构来找到它们,但我无法开始描述这种方法的危险性和脆弱性。您正尝试将此应用于系统中的每个表格视图,您希望这只是您的意思的表格视图(即您的表格视图)。但是系统或第三方库可能使用的表视图呢?你也在修改它们。当你试图理解这导致的崩溃时,由于混乱,堆栈跟踪将变得难以理解。

为了使其正常工作,tableView:cellForRowAtIndexPath:还需要正确处理这个额外的行,因此很难看到系统中的每个表视图控制器如何在不知道的情况下正确实现这个+1。

要么是你的表视图控制器的子类(并让它们调用super),要么使用一个单独的对象,如果需要,所有这些对象都会调用额外的行。这个其他对象(或超类)也是你应该处理这个额外行的单元格的地方。

答案 1 :(得分:1)

我在调酒方面经验不多。但我有两个可能的解决方案来解决你的问题。

第一: 创建一个子类:YouBaseTableView:UITableView,并在YouBaseTableView中添加一行。并从YouBaseTableView继承所有表视图类。

第二: 为UITableView创建扩展,并在此扩展名中写下您的行。

答案 2 :(得分:1)

我可能迟到了火车...... 但是为了将来参考,问题的解决方案是调用UITableView的setDataSource并将其替换为NSProxy实例。 通常没有人会覆盖setDelegate / setDataSource方法,这样就可以调整这些方法并拦截对这些代理的所有调用并交换实现。

查看此信息以获取更多信息:https://developer.apple.com/documentation/foundation/nsproxy

答案 3 :(得分:0)

您将进入两个需要完全理解才能正确使用并且非常危险的区域:在+ load方法中执行代码,并使用方法调配。我绝不敢在+加载中做任何事情。如果你知道自己在做什么,那么+ initialize就可以了,但如果你在这里提问,那么+ load就是你甚至都不应该想到的。

现在首先问自己:类方法中的“自我”是什么,什么是“[自我类]”?你认为这甚至有机会工作吗?

我还建议您谷歌搜索“swizzle”并选择一些其他代码进行方法调整。这对我来说看起来很可疑。把它写成一个类别而不是普通的C函数感觉太可怕了。