2013-05-10 44 views
0

,我需要更多的行爲添加到我需要延長,即實現方法,看起來像到的方法添加附加行爲沒有子

- (void)extendMethod:(SEL)selector forClass:(Class)class withCompletionBlock:(void (^)(void))completionBlock; 

所以每次Class實例調用的方法與另外SEL選擇方法應該被調用我的完成塊

我試過方法調配,但遇到了一些問題:我想調用原始方法實現。

我需要的是與子類非常相似,但是這應該被實現而沒有子類

UPDATE:

比如我的UIViewController子命名MyViewControllerMyViewController- (void)viewDidLoad方法。某處在應用程序調用我的方法

[methodExtender extendMethod:@selector(viewDidLoad) 
        forClass:[MyViewController class] 
     withCompletionBlock:^{ 
      NSLog(@"view did load called"); 
     }]; 

所以後調用MyViewController我完成塊的每個實例的viewDidLoad方法。

+0

都是阻塞的方法嗎? – 2013-05-10 14:47:47

+0

@DanShelly,對不起,我不明白你的評論 – user1248568 2013-05-10 14:49:25

+0

是你需要調用的原始方法阻止正在執行的線程,直到完成? – 2013-05-10 14:50:03

回答

1

我不確定你想如何使用選擇器,但你可以嘗試擴展任何類(即使沒有實現文件),通過Objective-C中的機制知道爲「類別」。要在其上進行

  1. 從上文件 - Xcode中點擊>新建 - >文件(命令+ N)
  2. 從可可觸摸選擇的Objective-C類的類
  3. 類型名稱,然後選擇類類別(我選擇UIButton)
  4. 然後下一步和創建。

的Xcode將爲例如兩個文件:UIButton+extendMethod.h 聲明你的方法在頭文件和* .m文件執行。

使用

如果你想在使用假設你的視圖控制器中的* .h文件導入 #import "UIButton+extendMethod.h"

,然後你可以打電話給你的方法是這樣的:

UIButton *button = [[UIButton alloc] init]; [button extendMethod:@selector(yourMethod:)];

+0

根據[documentation](http://developer.apple.com/library /ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html#//apple_ref/doc/uid/TP40011210-CH6-SW4)我無法使用類別來覆蓋父類的方法 – user1248568 2013-05-10 15:09:21

0

Swizzling確實允許你調用原始實現,雖然它只是有點混淆。因爲實現被混寫後換,您可以使用絞合方法的選擇調用原始的實現:

- (void)mySwizzledImplementation { 
    // do stuff 
    // now call original implementation (using swizzled selector!) 
    [self mySwizzledImplementation]; 
    // do more stuff 
} 

http://cocoadev.com/wiki/MethodSwizzling

0

看有沒有辦法(再)來模擬繼承沒有子。有用來擺姿勢,方法swizzling是所有剩下的(不像擺姿勢優雅)。這裏有一種方法可以正確調用方法,同時可以調用原始實現。

int swizzle_instance_methods(Class class, SEL selector, IMP replacement, IMP *store) { 

    @synchronized(class) { 
     Method method = class_getInstanceMethod(class, selector); 
     IMP original_imp = NULL; 

     if (method != NULL) { 
      const char *type = method_getTypeEncoding(method); 
      IMP original_imp = class_replaceMethod(class, selector, replacement, type); 
      if (original_imp == NULL) 
       original_imp = method_getImplementation(method); 

      if (original_imp != NULL && store != NULL) { 
       *store = original_imp; 
      } 
     } 
     return (original_imp != NULL); 
    } 
} 

+ (void) load 
{ 
    static IMP originalMethodImpl = NULL; 
    IMP customMethodImpl = imp_implementationWithBlock(^(id self_) { 
     NSString *descr = ((NSString(*)(id,SEL))originalMethodImpl)(self_, @selector(description); 
     return [NSString stringWithFormat:@"<--- %@ --->",descr]; 
    }); 

    swizzle_instance_methods([self class], @selector(description), customMethodImpl, &originalMethodImpl); 
} 

我可能會補充說這對調試很好,我認爲它可以構建出色的框架。唉,蘋果公司似乎有不同的想法,使用方法調配可能導致你的應用程序被排除在App Store之外。如果你沒有瞄準應用商店,那麼你的所有權力。

0

這是可能與ObjC類別。例如,您可以如下擴展NSString的hasPrefix方法:

-(BOOL)hasPrefixx:(NSString *)aString 
{ 
    NSLog(@"Checking has prefix"); 
    return [self hasPrefix:aString]; 

} 

如果您導入類別,則應該可以調用此方法。但他的意思是你改變了你打電話的方法。

順便說一下,方法swizzling應該工作。解釋位here

相關問題