2010-04-07 25 views
6

Tôi đang cố gắng tìm hiểu cách viết plugin bằng cách sử dụng SIMBL. Tôi đã nhận được plugin của tôi để tải với các ứng dụng đích, và cũng biết phương pháp mà tôi muốn ghi đè lên. Tuy nhiên, tôi không thể sử dụng class_getInstanceMethod một cách chính xác dựa trên các đoạn mã trên Internet. Có mọi thứ đã thay đổi trong OSX 10.6 và/hoặc ObjC2 không?Làm thế nào để tự động thay thế một phương thức triển khai thực hiện trong ObjC2?

Các mã sau đây từ culater.net cho "con trỏ dereferencing để loại không đầy đủ" trên báo cáo kết quả thứ hai cuối cùng:

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; 
} 

Có một ví dụ đầy đủ về cách ghi đè lên một phương pháp sử dụng plugin SIMBL? Cảm ơn!

Trả lời

5

Nếu bạn đang tìm kiếm swizzle a method, bạn có thể cân nhắc sử dụng the method_exchangeImplementations function để thay thế.

+0

Đó làm việc. Cảm ơn! – Abhi

+0

Peter - là nó cũng có thể làm được 'chức năng swizzling', ví dụ: thay thế việc thực hiện một chức năng đó không phải là một phương pháp của một lớp học? – Abhi

+2

Không. Phương thức này hoạt động vì việc triển khai bộ chọn sẽ tự động tra cứu khoảnh khắc bạn gửi tin nhắn — tức là vào thời gian chạy. Có một tên, là bộ chọn, và một giá trị, đó là việc thực hiện, và swizzling hoán đổi một giá trị khác, không giống như thay đổi các giá trị trong một từ điển. Các hàm không được tra cứu động; địa chỉ bị ràng buộc khi tệp thực thi được tải và vẫn cố định sau đó, và cuộc gọi đi trực tiếp đến địa chỉ đó, vì vậy không có gì để remap. –

7

Thời gian chạy obj-C đã thay đổi trong Objective-C 2, mã bạn trích dẫn sử dụng cũ một.

(Vâng, trên các ứng dụng 32 bit, sẽ chính xác hơn khi có hai giao diện cho cùng một thời gian chạy, tùy thuộc vào cách bạn biên dịch nhị phân của bạn; cả hai đều hoạt động ở cuối. Mục tiêu-C 2. Và bạn nên sử dụng các API mới hơn vì nó dễ sử dụng hơn và nó hoạt động cả trong 32 bit và 64 bit.)

Tham chiếu mới là the Guidethe Reference. Thay đổi cơ bản là nội bộ struct không còn công khai nữa, mờ đục. Vì vậy, bạn không thể truy cập trực tiếp vào thành viên của nó. Thay vào đó, bạn cần sử dụng API.

Thông thường mọi việc dễ dàng hơn trong thời gian chạy mới. Để thay thế một IMP, người ta chỉ sử dụng

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

Để có được mã hóa chủng loại, sử dụng

const char * method_getTypeEncoding(Method method); 

so với phương pháp ban đầu bạn đang thay thế. Trong thực tế, đó sẽ là

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

Để tìm hiểu thêm về thời gian chạy, tôi chân thành đề nghị loạt bài đăng blog tuyệt vời Friday Q&A bởi Mike Ash.

Hãy vui vẻ và may mắn!

Các vấn đề liên quan