2012-03-25 14 views
32

Jestem zdezorientowany z bridge i bridge_transfer, czy to prawda?Most iOS vs bridge_transfer

-(void)getData{ 
    ABAddressBookRef addressBook = ABAddressBookCreate(); 
    NSArray *allPeople = (__bridge_transfer NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook); 

    NSString *name; 
    for (int i = 0; i < [allPeople count]; i++) 
    { 
     name = (__bridge_transfer NSString *) ABRecordCopyValue((__bridge ABRecordRef)[allPeople objectAtIndex:i], kABPersonFirstNameProperty); 
    } 
    CFRelease(addressBook); 
    allPeople = nil; 
} 

Czy jest ktoś, kto może mi wytłumaczyć, jak z nich korzystać?

Odpowiedz

41

Jeśli masz włączone automatyczne liczenie odwołań (ARC), kod jest prawidłowy.

Istnieją dwa __bridge_transfer w swoich wyciągach. W rezultacie własność utworzonych elementów CFO zostanie przeniesiona do NSObjects. Jeśli masz włączone ARC, zostaną one automatycznie zwolnione. Jeśli zamiast tych 2 instrukcji użyłeś __bridge, będziesz musiał jawnie wywołać CFRelease, aby zwolnić CFObjects utworzone przez interfejs API *Copy.

Instrukcja __bridge jest również poprawna. Ponieważ odwołujesz się do NSObject w CF API. Nie przekazujesz własności, więc ARC ją zwolni.

+0

thx, czy możesz wyjaśnić, co oznacza "przenoszenie własności"? – Rinat

+8

Własność to ważna kluczowa koncepcja w zarządzaniu pamięcią. "Właściciel" obiektu jest odpowiedzialny za zwolnienie jego pamięci. Jeśli tego nie zrobi, obiekt wycieknie. Obiekt może mieć więcej niż jednego właściciela, więc ostatni właściciel, który wykracza poza zakres, jest odpowiedzialny za deallokację w tym przypadku. ARC robi to automatycznie, ale TYLKO dla obiektów C-Object. Obiekty CoreFoundation są obiektami waniliowymi C, więc musisz podać wskazówki kompilatora, jak sobie z nimi radzić. Jeśli "przeniesiesz własność" na ARC, mówisz, że ARC jest odpowiedzialna za zwolnienie obiektu. – borrrden

+2

Przepraszamy za spóźnienie w odpowiedzi. Własność dotyczy głównie tego, kto jest odpowiedzialny za uwolnienie obiektu. Jeśli chcesz uzyskać szczegółowe informacje, zapoznaj się z [Polityka własności] (https://developer.apple.com/library/mac/#documentation/CoreFOundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html). –

19

Jest to bardzo proste. Kiedy używasz ARC (automatyczne liczenie odnośników), kompilator zadba o to, ile obiektów są wskazywane przez zmienne. Kiedy liczba trafi do 0, obiekt jest automatycznie dealocated. W przypadku rzeczy, które pochodzą z niskiego poziomu struktury, takich jak podstawowe podstawy, kompilator nie wie, co robić. Więc używasz BRIDGE, jeśli chcesz po prostu powiedzieć kompilatorowi "zignoruj ​​ten, wydam go, kiedy go potrzebuję". lub Bridge transfer, jeśli chcesz powiedzieć "Traktuj to jako obiekt i zwolnij go, gdy odwołanie się do 0)."

Kiedy to zrobisz, tworzymy kopię, która w normalnych okolicznościach powinna zostać wydana przez "CFRelease" :

ABAddressBookCopyArrayOfAllPeople(addressBook) 

jednak dodając to, jesteś przeniesienie własności do obiektu objective-c:.

NSArray *allPeople = (__bridge_transfer NSArray*)........ 

Więc NSArray będzie zarządzany przez ARC


Zauważ, że jak wspomina JRG, to robi:

CFRelease(addressBook); 

Nie wpływa na nowo utworzony obiekt w każdym razie, ale zamiast oryginalnego jeden, który trzeba jeszcze ręcznie zwolnić: (Łatwo powiedzieć ponieważ metody te zwykle mają tworzyć lub skopiować słów kluczowych w ich nazw)


coś, co nie zdarza w twoim kodzie, ale powinieneś być ostrożny z tym, że uwolnienie podstawowych obiektów fundamentowych, które są NULL z CFRelease spowoduje błąd. Jak wspomina Paul w swoim komentarzu.

+2

W przeciwieństwie do '[nil release]', które jest w porządku, 'CFRelease (NULL)' powoduje błąd. – paulmelnikow

+1

Tak, masz rację, http://developer.apple.com/library/ios/#documentation/CoreFoundation/Reference/CFTypeRef/Reference/reference.html "Jeśli cf ma wartość NULL, spowoduje to błąd runtime i twoja aplikacja będzie wypadek." – Pochi

+0

-1: 'NSArray * allPeople = (__bridge_transfer NSArray *) ABAddressBookCopyArrayOfAllPeople (addressBook);' przenosi własność zwróconej tablicy. Nie ma to nic wspólnego z 'addressBook'. Zamiast tego 'addressBook' musi zostać wydany, ponieważ został utworzony za pomocą metody" create "(' ABAddressBookCreate'). W przeciwnym razie wycieknie. –

0

Jeden edit: Wierzę nazywając CFRelease na nil obiektu powoduje awarię aplikacji

1

Luis Oscara wciąż pracuję mój zrozumienia ARC, ale wierzę adresowa musi CFRelease. ARC nie zarządza książką adresową. NSArray * allPeople jest zarządzany przez ARC za pomocą wskazania odlewu __bridge_transfer i jest tworzony jako kopia oryginału. Bez CFRelease, bookBook wycieknie.

Powiązane problemy