2010-04-07 63 views
6

我想學習如何使用SIMBL編寫插件。我有我的插件來加載目標應用程序,也知道我想覆蓋的方法。但是,我無法正確使用基於Internet上的片段的class_getInstanceMethod。在OSX 10.6和/或ObjC2中改變了什麼?如何動態替換ObjC2中的方法實現?

culater.net下面的代碼給出了倒數第二個聲明「提領指向不完全類型」:

BOOL DTRenameSelector(Class _class, SEL _oldSelector, SEL _newSelector) 
{ 
    Method method = nil; 

    // First, look for the methods 
    method = class_getInstanceMethod(_class, _oldSelector); 
    if (method == nil) 
     return NO; 

    method->method_name = _newSelector; 
    return YES; 
} 

有如何重寫使用SIMBL插件的方法一個完整的例子嗎?謝謝!

回答

5

如果你正在尋找swizzle a method,你可以考慮使用the method_exchangeImplementations function來代替。

+0

工作。謝謝! – Abhi 2010-04-08 15:25:12

+0

Peter - 是否也可以做'功能調整',即替換不是一個類的方法的函數的實現? – Abhi 2010-04-08 16:03:04

+2

編號方法調整工作原理是因爲在您發送消息時即在運行時動態查找選擇器的實現。有一個名稱是選擇器,一個是實現的值,並且將一個值換成另一個值,與更改字典中的值不同。函數不是動態查找的;地址在可執行文件加載時被綁定,並在此後保持固定,並且調用直接進入該地址,因此沒有任何可重新映射。 – 2010-04-08 16:42:56

7

Objective-C 2中的Obj-C運行時已更改,您引用的代碼使用較舊的代碼。 (在32位應用中,根據你編譯二進制文件的方式,有兩個接口可以運行在同一個運行時更爲正確;兩者都最終工作,但更容易認爲事情發生了改變Objective-C 2.你應該使用更新的API,因爲它更容易使用,並且它可以在32位和64位兩者中使用。)

新引用是the Guidethe Reference。基本的變化是內部struct不再公開,是不透明的。所以你不能直接訪問它的成員。相反,您需要使用API​​。

通常情況下,新運行時中的事情更容易。要更換IMP,一個只使用

IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types); 

要獲得的編碼類型,使用

const char * method_getTypeEncoding(Method method); 

對你替換了原來的方法。在實踐中,這將是

method_getTypeEncoding(class_getInstanceMethod([SomeClass class], @selector(someSelector:you:want:to:replace:))); 

要了解更多有關運行時,我衷心推薦精彩的系列博客文章Friday Q&A由Mike灰。

玩得開心,祝你好運!