2014-05-07 22 views
8

Aşağıdaki kod parçası, Apple'ın ObjC çalışma zamanı (libobjc) kaynak kodundan alınmıştır. Bunun tam olarak ne anlama geldiğini merak ediyorum. (Çok google-mümkün değil, üzgünüm)Bu satır içi derleme neden libobjc'de serbest bırakılması, saklanması ve otomatikleştirilmesi çağrılıyor?

// HACK -- the use of these functions must be after the @implementation 
id bypass_msgSend_retain(NSObject *obj) asm("-[NSObject retain]"); 
void bypass_msgSend_release(NSObject *obj) asm("-[NSObject release]"); 
id bypass_msgSend_autorelease(NSObject *obj) asm("-[NSObject autorelease]"); 

Güncelleme: İşte

bypass_msgSend_release() yapılan bir çağrı oluşturur şeydir:

movl -4(%ebp), %eax 
movl %eax, (%esp) 
calll "-[NSObject release]" 
+1

olanlar aynı itiraz derleyici'nın arzusunu engelleyecek şekilde, açık korumak ait çağırmaları, serbest bırakılması ve sallanmasını görünmektedir. Neden olduklarına dair bir fikrim yok. –

+0

Bu dosya hangi dosyada? –

+0

http://opensource.apple.com/source/objc4/objc4-532.2/runtime/NSObject.mm –

cevap

4

Burada sonradan gelen retain fiili uygulama var dosyada:

__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; 
} 

Eğer etiketli bir işaretçi ise, hiçbir şey yapmayın. Yeterince adil, bu aslında yığındaki herhangi bir şeyle ilgili olmadığı anlamına gelir ve korunma sayımı yoktur.

Aksi eski günlerde onlar sadece mesaj nesnesine retain ediyorum. Bir özel retain (eski çalışma zamanı kayıt olacak hiçbir şüphe yok bir şey, dolayısıyla sürüm kontrolü) içerdiği not edilmişse Şimdi nesneye mesaj retain aksi takdirde bypass yöntemi kullanın.

baypas [NSObject retain] bilinen adrese doğrudan çağırmak için görünür.

Yani benim tahminim? Bu bir hız optimizasyonu. Özel bir saklamanın olmadığını ve gerçekte IMP'a atlayabileceğinizi söylerseniz, dinamik gönderim maliyetini de kaydedersiniz. Derleyicinin artık ARC (otomatik olarak Objective-C çağrıları değil) altında otomatik olarak C çağrılarına attığını düşünürsek, bu da asla daha pahalı şeylere girmeyeceğiniz anlamına gelir.

+0

Bu çok anlam ifade ediyor ve bypass_msgSend_ işlevini açıklıyor. Sadece oraya atla, dans et! : D –