ARC ve köprülü döküm


166

ARC ile, ben artık yayın yapabilirsiniz CGColorRefiçin id. Köprülü bir kadro yapmam gerektiğini öğrendim. Clang belgelerine göre :

Bir köprülü dökme C tarzı dökme üç anahtar kelimelerden biriyle açıklamalı edilir:

(__bridge T) opişleneni hedef türüne çevirir T. Eğer T bir retainable nesne işaretçisi türüdür, daha sonra op, bir sigara retainable işaretçi türü olmalıdır. Eğer Tolmayan bir retainable işaretçi türüdür, daha sonra op retainable nesne işaretçisi türü olmalıdır. Aksi takdirde alçı kötü şekillendirilir. Mülkiyet devri yoktur ve ARC tutma işlemleri eklemez.

(__bridge_retained T) opsaklanabilir nesne işaretçisi türüne sahip olması gereken işleneni, saklanamayan işaretçi türü olması gereken hedef türüne çevirir. ARC, yerel değerler üzerindeki olağan optimizasyonlara tabi olarak değeri korur ve alıcı + 1'in dengelenmesinden sorumludur.

(__bridge_transfer T) opsaklanamayan işaretçi türüne sahip olması gereken işleneni, saklanabilir nesne işaretçi türü olması gereken hedef türüne çevirir. ARC, yerel değerlerde olağan optimizasyonlara tabi olarak, çevreleyen tam ifadenin sonundaki değeri yayınlayacaktır.

Bu kalıplar, ARC kontrolüne giren ve çıkan nesneleri aktarmak için gereklidir; korunabilir nesne işaretleyicilerinin dönüştürülmesine ilişkin bölümdeki gerekçeye bakın.

ARC'yi sırasıyla dengesiz bir alıkoyma veya serbest bırakmaya ikna etmek için a __bridge_retainedveya __bridge_transfercast kullanılması zayıf formdur.

Her birini ne tür durumlarda kullanardım?

Örneğin, CAGradientLayerbir yer alır colorsbir dizi kabul özellik CGColorRefs. Tahminimce __brigeburada kullanmalıyım , ama tam olarak neden kullanmam (ya da etmemem) net değil.


17
WWDC 2011 oturumunu 323 izlediniz mi? Bu, ARC'yi burada yapabileceğimden çok daha iyi açıklıyor. Baştan sona tüm detayları kapsar. Her Mac / iOS geliştiricisi için mutlaka görülmesi gereken bir oturum.
rbrown


WWDC oturumuna bağlantı, bulmak önemsiz değildi: developer.apple.com/videos/play/wwdc2011/323 - Alakalı bit 23:15
Daniel

Yanıtlar:


215

Açıklamanın kafa karıştırıcı olduğunu kabul ediyorum. Onları az önce kavradığım için özetlemeye çalışacağım:

  • (__bridge_transfer <NSType>) opveya alternatif olarak CFBridgingRelease(op), ARC'ye CFTypeRefaktarılırken bir süre alıkoyma sayısını tüketmek için kullanılır . Bu aynı zamandaid someObj = (__bridge <NSType>) op; CFRelease(op);

  • (__bridge_retained <CFType>) opveya alternatif olarak CFBridgingRetain(op), NSObjectbir +1 alıkoyma sayısı verirken CF arazisine devralmak için kullanılır . CFTypeRefBu şekilde oluşturduğunuz bir sonucun sonucuyla aynı şekilde ele almalısınız CFStringCreateCopy(). Bu aynı zamandaCFRetain((__bridge CFType)op); CFTypeRef someTypeRef = (__bridge CFType)op;

  • __bridgesadece pointer-land ve Objective-C nesne-land arasında yayın yapar. Yukarıdaki dönüşümleri kullanmaya meyilli değilseniz, bunu kullanın.

Belki bu yardımcı olur. Kendimi, CFBridging…makroları sade dökümlere göre biraz tercih ediyorum .


__Bridge_transfer kullandığınızda, nesne tutma sayısı yayla 1 artar mı? Aksi takdirde, CFRelease () adı verildiği anda nesne gitti ve hiçbir şeye işaret etmiyor gibi görünüyor. Benzer şekilde __bridge_retain kullandığınızda, ARC op'un alıkoyma sayısını 1 azaltır mı? Yoksa nesnenin asla düzgün bir şekilde serbest bırakılmayacağı anlaşılıyor.
Tony

2
ARC topraklarına girdikten sonra artık sayıları tutmayı düşünmüyorsunuz, sadece güçlü ve zayıf referanslar hakkında.
Maymun

4
Evet, eğer sadece ark topraklarında güçlü / zayıf olursanız yeterli olacaktır, ancak ark ve ark olmayan ortamlar arasında nesneleri değiştirirken, hala başlık altında kalan sayım sonuçlarını düşünmek zorundasınız
Tony

3
Pek sayılmaz. Sadece ARC arazisine girip çıkmayı düşünmelisin. Ve bu, otomatik yayınlamayı kavramak için oldukça mantıklı. (ilginç bir şekilde: ARC, bir nesneyi sözlükten çıkarmak ve kullanmadan önce kaldırmak gibi ortak bir deseni düzeltir.)
monkeydom 13:12

3
Analyzer aracını (shift + command + B) kullanmak, geçerli kodun bellek sızdırıyorsa size doğal bir dilde söyleyeceği için bu tür şüphelerin çözülmesine yardımcı olabilir. Varsa, alıkoymayan bir alçı kullanmanız gerekirken muhtemelen alıkoyma dökümünü kullanıyorsunuzdur. Analizör bu kod satırlarındaki herhangi bir şey hakkında sizi
uyarmazsa

55

İOS belgelerinde, anlaşılması daha kolay olduğunu düşündüğüm başka bir açıklama buldum:

  • __bridge Mülkiyet devri olmadan Objective-C ve Core Foundation arasında bir işaretçi aktarır.

  • __bridge_retained (CFBridgingRetain)bir Objective-C işaretçisini bir Core Foundation işaretçisine çevirir ve aynı zamanda sahipliği size aktarır.

    Sen sorumlu olan nesnenin bırakmak mülkiyete CFRelease veya ilgili işlevini çağırmak için.

  • __bridge_transfer (CFBridgingRelease)hareket eder olmayan Amaç-Cı işaretçi Amaç-C de ve ARC sahipliği aktarır.

    ARC, nesnenin sahipliğinden feragat etmekten sorumludur .

Kaynak: Ücretsiz Köprü Çeşitleri


33

Bir takip olarak, bu özel durumda, iOS'taysanız Apple -CGColor, CGColorRef'i NSArray'e döndürmek için UIColor ve yöntemini kullanmanızı önerir colors. Gelen ARC Sürüm Notları geçiş , bölümünde "Derleyici CF Kakao Yöntemleri itibaren döndü Nesneler Kolları", yöntem kullanmayı belirtilmektedir -CGColorhangi bir Çekirdek Vakfı nesne otomatik olarak derleyici tarafından düzgün bir şekilde ele alınacaktır döndürür.

Böylece, aşağıdaki gibi kod kullanmanızı önerirler:

CAGradientLayer *gradientLayer = (CAGradientLayer *)[self layer];
gradientLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor darkGrayColor] CGColor],
                                                 (id)[[UIColor lightGrayColor] CGColor], nil];

Şu an itibariyle, Apple'ın örnek kodunda, bir derleyici hatasından kaçınmak için hala gerekli olan (id) dökümünü eksik olduğunu unutmayın.


İsterseniz, genellikle nesnelerin ilkini hepsi yerine (id) öğesine dökerek kurtulabilirsiniz.
Philippe Sabourin

1
Bu soru, yapıştırdığınız kodun yasal olmadığı ARC ile yayınlama hakkında soru soruyor.
Joey Hagedorn

11
@JoeyHagedorn - Belki de cevabımın ilk cümlesinde ARC belgelerine olan referansımı kaçırdınız, ancak sadece ARC altında bu geçerli değil, bu UIColor dönüştürücü yöntemlerinden NSArray'lara CGColorRef referansları sağlamak için önerilen yaklaşımdır. Ben ve diğerleri, ARC etkin uygulamalarda bu kodu kullanır. Bir Core Foundation nesnesini döndüren bir yöntemden (id) 'ye anında yapılan döküm, o nesneyi otomatik olarak ARC'ye doğru şekilde köprüler.
Brad Larson
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.