Đây là việc thực hiện thực tế của retain
từ sau trong tệp:
__attribute__((aligned(16)))
id
objc_retain(id obj)
{
if (!obj || OBJC_IS_TAGGED_PTR(obj)) {
goto out_slow;
}
#if __OBJC2__
if (((class_t *)obj->isa)->hasCustomRR()) {
return [obj retain];
}
return bypass_msgSend_retain(obj);
#else
return [obj retain];
#endif
out_slow:
// clang really wants to reorder the "mov %rdi, %rax" early
// force better code gen with a data barrier
asm volatile("");
return obj;
}
Vì vậy, nếu đó là một con trỏ được gắn thẻ, không làm gì cả. Đủ công bằng, điều đó có nghĩa là nó không thực sự liên quan đến bất cứ thứ gì trên heap và không có số lượng giữ lại.
Nếu không trong những ngày cũ, họ chỉ cần nhắn tin retain
cho đối tượng. Bây giờ họ nhắn tin retain
cho đối tượng nếu nó đã được ghi chú có chứa một tùy chỉnh retain
(không có nghi ngờ không phải là một cái gì đó thời gian chạy cũ sẽ ghi lại, do đó kiểm tra phiên bản) nếu không họ sử dụng phương pháp bỏ qua.
Đường vòng xuất hiện để gọi trực tiếp vào địa chỉ đã biết của [NSObject retain]
.
Vì vậy, tôi đoán? Đó là một tối ưu hóa tốc độ. Nếu bạn có thể nói rằng không có tùy chỉnh giữ lại và, trong thực tế, nhảy thẳng đến IMP
sau đó bạn tiết kiệm chi phí của công văn năng động. Cho rằng trình biên dịch bây giờ ném trong C cuộc gọi tự động dưới ARC (đáng chú ý không phải là các cuộc gọi Objective-C) có nghĩa là bạn không bao giờ đi vào những thứ đắt tiền hơn.
Chúng xuất hiện để được yêu cầu rõ ràng về giữ lại, phát hành và tự động chạy, để phá vỡ mong muốn của trình biên dịch đối tượng giống nhau. Về lý do tại sao họ có mặt, tôi không có một đầu mối. –
Tệp này có ở đâu? –
http://opensource.apple.com/source/objc4/objc4-532.2/runtime/NSObject.mm –