Inside Objc Class

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.

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:

objc_class data struct

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_classLưu trữ địa chỉ của class cha
cacheChứa cache của class, thường dùng để tăng tốc độ lookup implementation
bitsLư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

flagsLưu trữ một số flag đặc biệt
instanceStartOffset bắt đầu của ivar
instanceSizeKích thước cần để tạo object
reservedĐể dành
nameTên class
baseMethodListDanh sách method
baseProtocolsDanh sách property
ivarsDanh sách ivar
weakIvarLayoutDanh sách weak ivar
basePropertiesDanh 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.

Leave a Reply