Như những bài trước mình đã trình bày, object sẽ chứa một trường là isa. Từ isa thì runtime sẽ lấy được thông tin của class đó. Và từ đó dùng nó để gọi hàm khi chúng ta gọi hàm trong objc. Thì hôm nay chúng ta sẽ tìm hiểu về cơ chế Message Dispatch – cách gọi hàm của objc thực chất hoạt động như thế nào.
Series này được chia thành nhiều phần.
- Phần 1: Khái niệm, ưu nhược điểm.
- Phẩn 2: Chúng ta có thể làm gì với objc runtime.
- Phần 3: Swift & Objc Runtime
- Phần 4: Inside Objc Class
- Phần 5: Message dispatch
Chúng ta có chương trình demo như sau.
@interface HelloClass : NSObject - (void) hello; @end @implementation HelloClass - (void)hello { NSLog(@"Hello world"); } @end int main(int argc, const char * argv[]) { @autoreleasepool { HelloClass *obj = [[HelloClass alloc] init]; [obj hello]; } return 0; }
Khi chương trình thực hiện [obj hello]
. Chương trình sẽ thực hiện gọi objc_msgSend(obj, @selector(hello))
. Khi đó cơ chế Message Dispatch sẽ hoạt động sẽ những bước sau.
- Step 1: Thực hiện gọi hàm
_class_lookupMethodAndLoadCache3
để tìm IMP ( Tìm địa chỉ của hàmhello
nằm ở đâu trên RAM) - Step 2:
_class_lookupMethodAndLoadCache3
tiếp tục gọi hàmlookUpImpOrForward
- Step 3:
lookUpImpOrForward
sẽ gọi hàmgetMethodNoSuper_nolock
để tìm IMP. - Step 4:
getMethodNoSuper_nolock
sẽ thực hiện tìm method nằm trong list methods. - Step 5: Nếu tìm thấy thì return, không tìm thấy thì đi tiếp Step 6
- Step 6: Kiểm tra có forward target không. Nếu có thì quay lại Step 1 với object được trả về từ hàm
forwardingTargetForSelector
. Nếu không thì crash. - Step 7: Sau khi đã có được địa chỉ của hàm
hello
năm trên RAM. Thì chương trình sẽ dùng lệnh JMP(x86/64 instruction) để nhảy tới phần code của hàmhello
.
Tổng kết
Vừa rồi là phần tóm tắt phần xử lý của cơ chế Message Dispatch trong objc Runtime. Phần implement bên dưới khá là phức tạp( Code của function objc_msgSend được viết bằng Assembly), các bạn có thể tìm hiểu thêm bằng cách đọc open source Objc4.
Như vậy là chúng ta đã đi hết series về Objc Runtime. Các bạn đón đọc các series kế tiếp của mình nhé.
Bạn viết hữu ích lắm bạn!
Cảm ơn bạn 🙂
Bài viết của bạn đi sâu về dưới của core objective c. Rất hay. Cảm ơn bạn