2012-01-10 12 views
5

Mike Ash has written this introduction to ARC nerede o gibi bir şey tanıtır:Yerel bir değişkeni ne zaman ve neden ARC kullanarak __weak olarak bildirmek isterdim?

__weak Foo *_weakFoo = [object foo]; 

Neden bir yerel geçici değişken için bunu yapmak ister ki? __weak, başvurulan nesne serbest ayrılır aktarılmaz, _weakFoo işaretçisini otomatik olarak sıfırlayacak bir sıfırlama başvurusudur. Ayrıca, __weak iOS'ta kullanılabilir> =

Ben sadece bu Bu her zaman bir nesneyi veya nil dönmesi bekleniyor

Foo *_weakFoo = [object foo]; 

?: yaptığımda belaya aday olacağını 5.. ARC ile hala hata benim

Foo *_weakFoo = [object foo]; 
[self doSomethingStupid]; // does something bad so foo gets deallocated 
[_weakFoo doIt]; // CRASH! msg sent to deallocated instance 0x123456 

bir şey: o artık bir nesne gerekmez biliyor Benim tahminim bu nedir? Nileye veya başka bir şeye işaretçi koyduğumda, daha önce başvurulan nesnenin artık bu sahibi tarafından ihtiyaç duyulmadığını ve bu nedenle belki de uzaklaşabileceğini anladım. Ama asıl nokta şu ki: Onu sıfırladım. Yani her neyse zaten!

ne zaman yerel bir değişken yapmak hissi için __weak ediyorum ve gerçekten bu gerektirecek kadar sersem ne tür başka bir yerde yapmak gerekir?

cevap

9

Ben korumak döngüsünü önlemek için bir bloğun self içini işlemek için varsa __weak yerel değişkenleri kullanın. GCD kullandığım bu örneği ve bir dize için ağ isteği gerçekleştirmek için blokları ve sonra da sınıfın bildirdiği bir etikete, bu durumda TurtlesViewController ayarını düşünün.

__weak TurtlesViewController *weakSelf = self; 
dispatch_queue_t networkQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 

dispatch_async(networkQueue, ^{ 

    // Kick off a network task for some data that is going to populate a label declared on our class 
    NSString *returnString = [networkDataSource retrieveTurtleTime]; 

    // Dispatch back to the main thread to populate the UILabel 
    dispatch_async(dispatch_get_main_queue(), ^{ 

     // Using self.label here creates a retain cycle. Self owns the block and the block has captured self 
     self.label.text = returnString; 

     // Instead, we use weakSelf for our reference to the label as it will be torn down by ARC at the end of the loop. 
     weakSelf.label.text = returnString; 
    }); 
}); 
+1

Nasıl olsa döngüsünü korumak olabilir? – openfrog

+1

@openfrog - Bu özel blok Ben NSNotificationCenter en '-addObserverForName kullanarak bildirimler (için blok tabanlı gözlemci olacağını yaşamanıza büyük bir döngü korumak olma riskiyle ama biri olmayabilir: Nesne: kuyruğunu: usingBlock:'). Bir nesnede böyle bir gözlemci kurarsanız ve 'self'de bir şeye başvurursanız, nesne blokta bekledikçe ve blok nesne üzerinde durduğunda bir döngü kurarsınız. –

+2

Bunu yazdıktan sonra bunun en iyi örnek olmadığını anladım çünkü dispatch_async() bloğu kopyalar, ancak sadece yöntemin sonuna kadar. Daha iyi bir örnek NSBlockOperation'ı kullanmakta olup, bunun bir örneği, nesnenin kullanım ömrü boyunca blokta geçirilmiş olması, döngüleri daha olası tutmasıdır. –

İlgili konular