Vraag ARC en overbrugde cast


Met ARC kan ik niet langer casten CGColorRef naar id. Ik heb geleerd dat ik een overbrugde cast moet doen. volgens clang docs:

EEN overbrugde cast is een cast in de C-stijl geannoteerd met een van de drie sleutelwoorden:

(__bridge T) op werpt de operand naar het bestemmingstype T. Als T   is een vasthoudoptiek aanwijzertype, dan op moet een hebben   niet-vasthoudbaar aanwijzertype. Als T is een niet-vasthoudbaar aanwijzertype,   dan moet op een vasthoudbaar objectaanwijzertype zijn. Anders de cast   is slecht gevormd. Er is geen eigendomsoverdracht en ARC voegt geen nummer in   bewerkingen behouden.

(__bridge_retained T) op werpt de operand, die moet hebben   vasthoudobject aanwijzer type, naar het bestemmingstype, dat moet zijn   een niet-vasthoudbaar aanwijzertype. ARC behoudt de waarde, afhankelijk van de   gebruikelijke optimalisaties op lokale waarden, en de ontvanger is verantwoordelijk   voor het in evenwicht brengen van die +1.

(__bridge_transfer T) op werpt de operand, die moet hebben   niet-vasthoudbaar aanwijzertype, naar het bestemmingstype, wat een a moet zijn   vasthoudobject aanwijzer type. ARC geeft de waarde aan het einde vrij   van de omsluitende volledige expressie, onder voorbehoud van de gebruikelijke optimalisaties   op lokale waarden.

Deze afgietsels zijn vereist om objecten in en uit te verplaatsen   ARC-besturing; zie de beweegreden in de sectie over conversie van   vasthoudbare objectwijzers.

Gebruik maken van een __bridge_retained of __bridge_transfer puur gegoten om te overtuigen   ARC voor het uitzenden van een niet-gebalanceerde retain of release is respectievelijk slecht   het formulier.

In wat voor soort situaties zou ik elk gebruiken?

Bijvoorbeeld, CAGradientLayer heeft een colors eigenschap die een reeks van accepteert CGColorRefs. Ik vermoed dat ik moet gebruiken __brige hier, maar precies waarom ik zou moeten (of zou moeten) is onduidelijk.


161
2017-08-12 06:24


oorsprong


antwoorden:


Ik ben het ermee eens dat de beschrijving verwarrend is. Omdat ik ze net heb begrepen, zal ik proberen samen te vatten:

  • (__bridge_transfer <NSType>) op Of anders CFBridgingRelease(op) wordt gebruikt om een ​​behoud-telling van a te consumeren CFTypeRef tijdens het overbrengen naar ARC. Dit kan ook worden weergegeven door id someObj = (__bridge <NSType>) op; CFRelease(op);

  • (__bridge_retained <CFType>) op Of anders CFBridgingRetain(op) wordt gebruikt om een NSObject over naar CF-land terwijl het een + 1-telling geeft. Je zou moeten omgaan met a CFTypeRef je maakt op deze manier hetzelfde als waarmee je een resultaat zou behandelen CFStringCreateCopy(). Dit kan ook worden weergegeven door CFRetain((__bridge CFType)op); CFTypeRef someTypeRef = (__bridge CFType)op;

  • __bridge zet gewoon tussen aanwijzerland en Object-C object-land. Als je geen neiging hebt om de bovenstaande conversies te gebruiken, gebruik deze dan.

Misschien is dit nuttig. Ik geef er de voorkeur aan CFBridging… macro's nogal een beetje over de vlakte afgietsels.


212
2017-08-31 18:23



Ik vond een andere verklaring in de iOS-documentatie die volgens mij gemakkelijker te begrijpen is:

  • __bridge draagt ​​een aanwijzer over tussen Objective-C en Core Foundation zonder overdracht van eigendom.

  • __bridge_retained (CFBridgingRetain) werpt een Doelstelling C pointer naar a Core Foundation aanwijzer en draagt ​​ook het eigendom aan u over.

    Jij bent verantwoordelijk voor het aanroepen van CFRelease of een gerelateerde functie om het eigendom van het object op te geven.

  • __bridge_transfer (CFBridgingRelease) beweegt een non-Objective-Cwijzer naar Objective-C en draagt ​​ook het eigendom over aan ARC.

    ARC is verantwoordelijk voor het afstand doen van het eigendom van het object.

Bron: Tolvrij gekoppelde typen


52
2017-10-29 17:02



Als vervolg hierop, in dit specifieke geval, beveelt Apple aan dat u UIColor en zijn -CGColor methode om de CGColorRef terug te zetten in de colors NSArray. In de Overgang naar ARC-releaseopmerkingen, onder de sectie "De samensteller behandelt CF-objecten geretourneerd van cacaomethoden", wordt aangegeven dat het gebruik van een methode zoals -CGColor die een Core Foundation-object retourneert, wordt door de compiler automatisch correct afgehandeld.

Daarom suggereren ze het gebruik van code zoals de volgende:

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

Merk op dat vanaf nu de voorbeeldcode van Apple de (id) cast mist die ik hierboven heb, wat nog steeds nodig is om een ​​compileerfout te voorkomen.


32
2017-10-18 03:28