Odlewy łukowe i mostkowe
Z ARC, nie mogę już rzucać CGColorRef
do id
. Nauczyłem się, że muszę zrobić gips pomostowy. Według clang docs :
A bridged cast jest obsadą w stylu C opatrzoną jednym z trzech słów kluczowych:
(__bridge T) op
rzuca operand na typ docelowyT
. IfT
jest typem wskaźnika obiektu, wtedyop
musi mieć nieosiągalny typ wskaźnika. IfT
jest nieprzetworzalnym typem wskaźnika, wtedy op musi mieć obiekt możliwy do uzyskania typ wskaźnika. Inaczej Obsada jest źle ukształtowany. Nie ma przeniesienia własności, a Arc wstawia nie zachowaj operacje.
(__bridge_retained T) op
rzuca operand, który musi mieć zwracalny typ wskaźnika obiektu, do typu docelowego, który musi być nieosiągalny typ wskaźnika. ARC zachowuje wartość, z zastrzeżeniem zwykłe optymalizacje wartości lokalnych, a odbiorca jest odpowiedzialny za wyważenie +1.
(__bridge_transfer T) op
rzuca operand, który musi mieć nieodwracalne typ wskaźnika, do typu docelowego, który musi być retainable object pointer type. ARC zwolni wartość na końcu pełnej ekspresji, z zastrzeżeniem zwyczajowych optymalizacji na lokalnych wartościach.Te odlewy są wymagane do przenoszenia obiektów w i z Sterowanie łukiem; zob. uzasadnienie w części dotyczącej konwersji retainable object pointers.
Używając
__bridge_retained
lub__bridge_transfer
rzucać wyłącznie, aby przekonać Łuk do emitowania niezrównoważonego zatrzymania lub uwolnienie, odpowiednio, jest słaba forma.
W jakich sytuacjach mógłbym użyć każdego z nich?
Na przykład, CAGradientLayer
ma właściwość colors
, która akceptuje tablicę CGColorRef
s. Domyślam się, że powinienem użyć __brige
tutaj, ale dokładnie dlaczego powinienem (lub nie powinienem) jest niejasne.
3 answers
Zgadzam się, że opis jest mylący. Ponieważ właśnie je uchwyciłem, postaram się podsumować:
(__bridge_transfer <NSType>) op
lub alternatywnieCFBridgingRelease(op)
jest używany do zużywania liczby zatrzymańCFTypeRef
Podczas przenoszenia jej na łuk. Może to być również reprezentowane przezid someObj = (__bridge <NSType>) op; CFRelease(op);
(__bridge_retained <CFType>) op
lub alternatywnieCFBridgingRetain(op)
jest używany do przekazaniaNSObject
do CF-land, dając mu liczbę zatrzymań +1. Powinieneś obsługiwaćCFTypeRef
tworzysz w ten sposób tak samo, jak byś obsługiwał wynikCFStringCreateCopy()
. Może to być również reprezentowane przezCFRetain((__bridge CFType)op); CFTypeRef someTypeRef = (__bridge CFType)op;
__bridge
tylko rzuca między pointer-land i Objective - C object-land. Jeśli nie masz ochoty korzystać z konwersji powyżej, użyj tej.
CFBridging…
raczej niż zwykłe odlewy.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-03 20:53:31
Znalazłem inne wyjaśnienie w dokumentacji iOS, które moim zdaniem jest łatwiejsze do zrozumienia:
__bridge
przenosi wskaźnik pomiędzy Objective-C i Core Foundation bez przeniesienia własności.-
__bridge_retained (CFBridgingRetain)
rzuca wskaźnik Objective-C na wskaźnik Core Foundation, a także przenosi własność na Ciebie.Jesteś odpowiedzialny za wywołanie CFRelease lub powiązanej funkcji w celu zrzeczenia się własności obiekt.
-
__bridge_transfer (CFBridgingRelease)
przenosi wskaźnik non-Objective-C do Objective-C , a także przenosi własność do ARC.ARC jest odpowiedzialny za zrzeczenie się własności obiektu.
Source: Toll-Free Bridged Types
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-15 14:46:29
Jako kontynuację, w tym konkretnym przypadku, jeśli używasz systemu IOS, Apple zaleca użycie UIColor i jego metody -CGColor
, aby zwrócić cgcolorref do colors
NSArray. W Transitioning to Arc Release Notes , pod sekcją "kompilator obsługuje obiekty CF zwracane z metod Cocoa", jest wskazane, że użycie metody takiej jak -CGColor
, która zwraca obiekt Core Foundation, będzie automatycznie obsługiwane poprawnie przez kompilator.
Sugerują więc użycie kodu takiego jak "po": {]}
CAGradientLayer *gradientLayer = (CAGradientLayer *)[self layer];
gradientLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor darkGrayColor] CGColor],
(id)[[UIColor lightGrayColor] CGColor], nil];
Zauważ, że w tej chwili w przykładowym kodzie Apple brakuje (id) cast, który mam powyżej, co jest nadal konieczne, aby uniknąć błędu kompilatora.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-18 03:28:57