Bài viết hôm nay chủ yếu nói về class trong Objc được implement như thế nào và tại sao objc runtime có thể biết được object đó thuộc class nào để gọi hàm.
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
1. Class
1.1 Define of class
Trong objc class được implement là một struct, nơi chứa tất cả thông tin của class đó như là isa, super class, name, version, info, instance_size, … chi tiết mình sẽ xem xét bên dưới.
Chúng ta cùng xem xét open source của objc4 trên github.
Quan sát thấy, Class type trong objective-c là kiểu con trỏ của struct objc_class
(typedef
struct
objc_class *Class
). ? objc_class
được define như sau:
class_ro_t
được tạo ra khi compile chứa các thông tin cố định.class_rw_t
được tạo ra khi runtime, chứa thông tin thêm về class. Ví dụ như khi chúng ta thêm một thuộc tính hoặc một method lúc runtime, thì thông tin sẽ được lưu trữ ở đây.
Dưới đây là bảng giải thích công dụng của các trường mà mình biết. Chủ yếu thông tin chính của class được lưu trữ trong struct class_ro_t
isa | Đây là nơi lưu trữ con trỏ isa chứa thông tin metaclass và 1 số thông tin khác nếu có. Metaclass mình sẽ nói ở phần sau của bài viết |
super_class | Lưu trữ địa chỉ của class cha |
cache | Chứa cache của class, thường dùng để tăng tốc độ lookup implementation |
bits | Lưu trữ địa chỉ của class_rw_t và 1 số thông tin khác(requiresraw_isa, hasdefault_rr, is_swift) |
Từ bits
objc runtime lấy được thông tin của class_rw_t
và tiếp đó lấy được thông tin chính của class từ class_ro_t
.
Giải thích một số field của class_ro_t
flags | Lưu trữ một số flag đặc biệt |
instanceStart | Offset bắt đầu của ivar |
instanceSize | Kích thước cần để tạo object |
reserved | Để dành |
name | Tên class |
baseMethodList | Danh sách method |
baseProtocols | Danh sách property |
ivars | Danh sách ivar |
weakIvarLayout | Danh sách weak ivar |
baseProperties | Danh sách property |
2.2 Thông tin define được sử dụng như thế nào
Khi compile, compiler sẽ thực hiện ghi thông tin class dưới dạng struct vào session __objc_data thuộc DATA segment để sử dụng trong runtime.
Dưới đây là một số hoạt động của objc runtime về vấn đề sửa dụng thông tin class.
- Khi khởi tạo object, objc runtime sẽ tiến hành lấy thông tin
instance_size
để khởi tạo từng ấy byte ở vùng nhớ heap để lưu trữ thông tin của class. Vùng nhớ này sẽ lưu trữ isa và các ivar của object đó. - Khi objc runtime cần gọi một method từ object. Nó sẽ tiến hành lấy thông tin của class và tìm method cần gọi trong
methodLists
.
2. Tại sao objc runtime biết được class của object đó
Cấu trúc của object là field đầu tiên (4 byte đối với 32bit và 8 byte đối với 64bit) chứa thông tin về isa.
Dựa vào isa thì runtime sẽ đọc ra được thông tin class và tìm đến danh sách method trong class và gọi hàm tương ứng với selector.
3. Metaclass
Ở mục 2 mình có nói field đầu tiên chứa isa – lưu thông tin về class. Vậy isa của class để lưu thông tin gì.
isa của class cũng lưu thông tin class của nó ?. Vậy class của nó là cái gì. Đó chính là metaclass.
Metaclass và class chính là một cặp class đi cùng với nhau để định nghĩa bất cứ class nào. Metaclass chính là class của class.
Bạn thực hiện gọi hàm [UIApplication sharedApplication]
chính là gọi hàm của class. Metaclass sẽ chứa thông tin về static method của class. Và cũng như object, objc runtime lấy thông tin ở list method để gọi hàm tương ứng.
Tổng kết
Vậy là chúng ta đã tìm hiểu về class được implement như thế nào, metaclass cũng như objc sử dụng trường isa để làm gì.
Cảm ơn các bạn đã đọc bài.