Adding method to instance of objective-c class at runtime

De openkb
Aller à : Navigation, rechercher

Sommaire

Questions

I am wondering if there is a way to add an instance method to an "instance" of a class.

The scenario is that I am using EKEventEditViewController and there is a UITableView inside this class with a delegate(UITableViewDelegate) called "EKEventEditor" (non-public AFAIK). It does not implements the tableView:willDisplayCell:forRowAtIndexPath: method, which I am trying to use to disable some cell.

So I am trying to add a method to the instance, but all I can find in the Obj-C runtime is the class_addMethod call which adds method to the class but not the instance. With "EKEventEditor" being private, I can t just extend it and add that method myself.

Any hints?

Here is the code that I am using, the function that i am trying to add (willDisplayCell_) is not getting called.

- (void)navigationController:(UINavigationController *)navigationController 
  willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {

if ([navigationController isKindOfClass:[EKEventEditViewController class]]) {

UITableViewController *rootController = (UITableViewController*)[(UINavigationController*)navigationController visibleViewController];
if ([rootController isKindOfClass:[UITableViewController class]]) {
  UITableView *eventTableView = (UITableView*)[rootController view];

  class_addMethod([eventTableView.delegate class], 
                  @selector(tableView:willDisplayCell:forRowAtIndexPath:), 
                  (IMP)willDisplayCell_, "v@:@@@");
}}} 


void willDisplayCell_(id self, SEL cmd, UITableView *tableView, UITableViewCell *cell, NSIndexPath *indexPath) {
  NSLog(@"CALLED?");
}

Answers

https://github.com/mralexgray/AtoZ.framework/blob/Core/AtoZ/Categories/NSObject-Utilities.h https://github.com/mralexgray/AtoZ.framework/blob/Core/AtoZ/Categories/NSObject-Utilities.h

@interface NSObject (AZOverride)
/** Dynamically overrides the specified method on this particular instance.
* The block s parameters and return type must match those of the method you 
* are overriding. However, the first parameter is always "id _self", which 
* points to the object itself.
* You do have to cast the block s type to (__bridge void *), e.g.:
*
*    [self az_overrideSelector:@selector(viewDidAppear:)
*            withBlock:(__bridge void *)^(id _self, BOOL animated) { ... }];
*/
- (BOOL)az_overrideSelector:(SEL)selector withBlock:(void *)block;
/** To call super from the overridden method, do the following:
*    SEL sel = @selector(viewDidAppear:);
*    void (*superIMP)(id, SEL, BOOL) = [_self az_superForSelector:sel];
*    superIMP(_self, sel, animated);
* This first gets a function pointer to the super method and then you call it.
*/
- (void *)az_superForSelector:(SEL)selector;
@end

Source

License : cc by-sa 3.0

http://stackoverflow.com/questions/11354049/adding-method-to-instance-of-objective-c-class-at-runtime

Related

Outils personnels
Espaces de noms

Variantes
Actions
Navigation
Outils