NermaN NermaN - 10 months ago 45
Objective-C Question

How to use method swizzle or something on subclasses

I has many UITableViewController subclasses in my app.

Now i just needed to modify them all to add +1 row in all cases, and one simple equal row in all.

I do not want to modify all of them by hand, better way seem's to replace UITableViewDataSource method to modify values in way like:

+(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;

But it replaces superclass function, that does not called in subclasses, so this is not working. Is there method to do that what i want, without modifying all subclasses?


You'd need to swizzle every subclass specifically. You can find them by introspecting the class hierarchy at runtime with objc_getClassList, but I can't begin to describe how dangerous and fragile this approach is. You're trying to apply this to every tableview in the system, which you hope is just the tableviews you mean it to be (i.e. your tableviews). But what about tableviews that might be used by the system or from third-party libraries? You're modifying them, too. And when you try to understand the crash this causes, the stack trace will be unintelligible because of the swizzle.

In order for this to work, tableView:cellForRowAtIndexPath: also needs to correctly handle this extra row, so it's hard to see how every table view controller in the system is going to be implemented correctly without knowing about this +1.

Either subclass your table view controller (and have them call super), or use a separate object that all of them call to add the extra row if it's needed. This other object (or superclass) is also where you should handle the cell for this extra row.