2010年6月20日 星期日

Objective-C 神奇的 exchange implementation

在 Objective-C 中,我們可以交換兩個相同 method signature 的 method 內的 implementation,會令 call method A 時實際上運行 method B 的 code,而 call method B 時會運行 method A 的 code。
我們可以利用這個功能,去 "hook" 一些 API,修改其運作方式,對於新手來說這個功能是很危險的,但對於清楚 API 運作的高手來說,這個功能很有用,可以做一些 API 本身沒有的功能。

ExchangeImp.h
@interface NSObject (ExchangeImp)

+ (BOOL)exchangeMethod:(SEL)origSelector withMethod:(SEL)newSelector;

@end

ExchangeImp.m
#import "ExchangeImp.h"

@implementation NSObject (ExchangeImp)

+ (BOOL)exchangeMethod:(SEL)origSelector withMethod:(SEL)newSelector
{
    Method orgMethod = class_getInstanceMethod(self, orgSelector);
    Method newMethod = class_getInstanceMethod(self, newSelector);

    if ((orgMethod != NULL) && (newMethod != NULL))
    {
        if (class_addMethod(self, orgSelector, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)))
        {
            class_replaceMethod(self, newSelector, method_getImplementation(orgMethod), method_getTypeEncoding(orgMethod));
        }
        else
        {
            method_exchangeImplementations(origMethod, newMethod);
        }
        return YES;
    }
    return NO;
}

@end

沒有留言:

張貼留言