2009-10-29 14 views
7

Istnieje wiele metod kakao, które wymagają obiektu NSError jako parametru do metody, ale tak naprawdę są środkiem zwracania obiektu błędu do metody wywołującej, jeśli istnieją błędy. Czy ten zwrócony obiekt został zachowany? Oznacza to, że w kodzie obiektu wywołującego (metoda, do której jest zwracany błąd), czy nie trzeba być jakiś kod jak:Czy muszę zwolnić zwrócony obiekt NSError?

NSError *error; 
    [apiCall .... error:&error]; 

    if (error){ 
    [*error release]; 
} 

Nie widziałem nigdzie, a jeśli to nie musi być zwolniony, czy to jest sposób na zrobienie tego?

Odpowiedz

7

Zwrócone obiekty są zwykle autoreleased. Ogólną zasadą jest, abyś zadzwonił pod numer auto-/release, jeśli wcześniej używałeś tego samego obiektu pod nazwą copy/alloc/retain. A ty nie dereference error w wywołaniu metody:

// right 
[error code] 
// wrong 
[*error code] 
+0

Powodem, dla którego umieściłem kod błędu [*] jest to, że można również podać NSError var jako: NSError ** error; Co jest punktem do punktu do obiektu. Czy to jest ważne? – casademora

+0

Podajesz 'NSError **' jako typ dla 'error' tylko wtedy, gdy jest to" out parameter "lub" output parameter ". W takim przypadku wyłuskiwałbyś, ale zwróć uwagę, że '* error' miałby typ' NSError * '. Używasz parametrów, aby ominąć fakt, że funkcje mają tylko jedną wartość zwracaną. Parametry wyjściowe w Objc-C używają 'Type **', ponieważ argumenty są wartościami typu pass-by-value. Zauważ także, że jeśli 'error' miał typ' NSError ** ', musiałbyś zainicjować go za pomocą wskaźnika do' NSError * '(co robisz w wywołaniu API) lub przydzielić wskaźnik, co się dzieje ale jest trochę dziwne. – outis

+0

@outis Jeśli jest autoodtwarzany, to nie używa go w metodzie wywołującej niepoprawny. Ponieważ zasięg metody, która faktycznie utworzył NSError * i przypisał go do parametru out NSError **, zakończył się wywołaniem metody i używamy go po tym w wywołującym. – SayeedHussain

4

Nie przydzielona pamięć do błędu, więc nie ma potrzeby, aby go zwolnić. Z reguły framework zazwyczaj dodaje autorelease do wszystkich obiektów, które tworzy.

6

Przeczytaj zasady pamięci na developer.apple.com Nigdy nie ufaj nikomu przekształcając je jak „ty wcześniej zwana kopia/Alloc/zachować” - to nie jest reguła, która faktycznie mówi coś w stylu „ty otrzymywałem obiektu za pośrednictwem metoda z kopią, nowym lub przydziałem jako częścią nazwy ". Ponownie, nie wierz mi, przeczytaj developer.apple.com

Co do NSError * *, to po prostu nie tak. METHOD przyjmuje NSError * * jako argument, czyli wskaźnik do NSError *. Jest to POINTER TO THE NSError *, który będzie wypełniony adresem NSError, który pochodzi z gdzieś i nie masz prawa zakładać, gdzie.

Możesz przekazać wskaźnik tylko do NSError * - wszystko inne jest złe.

Nie należy również zakładać, że NSError został automatycznie zwolniony. Może to być singleton, może to być dowolna liczba alternatywnych. Wszystko, co musisz wiedzieć, to to, że "nie zachowałeś go, nie musisz go wypuszczać".

+0

Polityka własności (http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmObjectOwnership.html # // apple_ref/doc/uid/20000043-SW1) jest to, że metody z copy/alloc/new imply własności (i zachować jawnie deklaruje własność), która określa, kto wysyła wiadomości o zwolnieniu. – outis

+0

Firmy zewnętrzne nie są zobowiązane do przestrzegania tych zasad, ale zaleceniem firmy Apple jest autorelease utworzony NSError przed zwróceniem go (http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ErrorHandlingCocoa/CreateCustomizeNSError/CreateCustomizeNSError .html # // apple_ref/doc/uid/TP40001806-CH204-SW5) – outis

+0

Stąd "ogólnie autoreleased" i "ogólna reguła". – outis

Powiązane problemy