Non-pointer isa

Bài viết này có thể không hữu ích về mặt lập trình, tuy nhiên sẽ giúp ta hiểu hơn về cấu trúc của isa và biết được objc runtime biết được object đó thuộc class nào.

Ở kiến trúc 32bit, thì isa được coi là pointer trỏ tới vùng nhớ định nghĩa class. Vì có isa nên objc runtime biết được object đó thuộc class nào. Tuy nhiên trên kiến trúc 64bit apple đã sửa đổi nên isa không còn là pointer nữa, nên chủ đề hôm nay của bài viết có tên là Non-pointer isa.

Trong kiến trúc 64bit thì isa có độ dài 64bit, còn kiến trúc 32bit thì isa có độ dài 32bit. Tính năng non-pointer isa chỉ có trên thiết bị chạy arm64, x86_64( iOS Simulator không có).

Theo object layout thì nó nằm tại đầu của object. Khi dùng lệnh sau trong lldb thì bạn sẽ thấy điều đó.

Command dump class table của class NSString

language objc class-table dump NSString -v
Sau khi chạy lệnh nó sẽ ra thông tin class như list ivar, property

1. Tại sao apple lại sửa như vậy

Khi sử dụng kiến trúc 64bit thì isa có độ dài 64bit, mà sử dụng 64bit chỉ để chứa địa chỉ vùng nhớ định nghĩa class thì quá dư thừa.

Chính vì vậy họ đã thêm vào đó một số thông tin khác. Cấu trúc mới của isa sẽ như sau. Mỗi field có đơn vị là bit.

2. Cấu trúc non-pointer isa

Tuỳ theo kiến trúc mà isa có các field có độ dài khác nhau giữa các kiến trúc. Các bạn có thể đọc về isa tại đây : http://github.com/opensource-apple/objc4

arm architecture

nonpointer: 1
has_assoc: 1
has_cxx_dtor: 1
shiftcls: 33
magic: 6
weakly_referenced: 1
deallocating: 1
has_sidetable_rc: 1
extra_rc: 19

x86_64 architecture

nonpointer: 1
has_assoc: 1
has_cxx_dtor: 1
shiftcls: 44
magic: 6
weakly_referenced: 1
deallocating: 1
has_sidetable_rc: 1
extra_rc: 8

Giải thích các trường

nonpointer: 0 là raw isa, 1 là non-pointer isa.
has_assoc: Object có được liên kết với object nào không, khi dùng objc_setAssociatedObject thì cờ này sẽ được bật lên 1
has_cxx_dtor: Xác định xem có gọi cxx_destruct hay không.
shiftcls: Chứa địa chỉ của vùng nhớ định nghĩa class
magic: Sử dụng để phân biệt đối tượng thực với rác chưa được khởi tạo.
weakly_referenced: Object có con trỏ weak nào trỏ tới không.
deallocating: Object đang được huỷ.
has_sidetable_rc: Có lưu trữ thêm retain count trong SideTable hay không.
extra_rc: Chứa thông tin Retain count. Ví dụ field này là 1 thì retain count là 2.

Dựa vào cấu trúc này, ta có thể lấy ra được thông tin số retain count của object là bao nhiêu nếu cờ has_sidetable_rc( thường bật khi số retain count lớn) không được bật.

Bài viết sau mình sẽ đề cập tới Side Table cũng như objc lưu trữ retain count như thế nào.

Cảm ơn các bạn đã đọc bài viết.

Tham khảo: http://www.sealiesoftware.com/blog/archive/2013/09/24/objc_explain_Non-pointer_isa.html