2013-03-18 59 views
2
-(NSData *)jsonRepresentation:(NSError **error)error { 
    NSDictionary *dict = [self getDictRepresentation]; 
    return [NSJSONSerialization dataWithJSONObject:dict options:nil error:error]; 
} 

// Some other place... 

NSError *__autoreleasing error = nil; 
NSData *json = [obj jsonRepresentation:&error]; 

自動釋放語義安全地傳達error堆棧到我的第二個代碼塊嗎?下面的iOS代碼是否安全? (__autoreleasing語義)

+0

那些自動釋放機制實際上隱含在局部變量中(有一些例外),並且不需要明確說明。但是,是的,這是正確的。 – 2013-03-18 21:20:53

+0

@ RichardJ.RossIII:你是什麼意思?除非另有說明,obj-c類型的局部變量默認爲'__strong'。 – 2013-03-18 21:26:11

+0

@KevinBallard我的意思是說,它們的行爲就像是一個自動釋放值,只要它們可以延長聲明塊的生命週期。返回值特別是變成__autoreleasing(除非你指定了另一個返回類型屬性)。在極少數情況下,__autoreleasing真的需要。 – 2013-03-18 21:28:46

回答

3

是的,這是正確的,但是您應該在方法聲明中指定此修飾符,而不是在變量聲明中指定。即使是蘋果的官方文件明確提到這個特別的情況:

__autoreleasing用於表示由引用(id *)通過,並於返回被自動釋放參數。

+0

然而,值得注意的是,你應該在方法聲明本身指定'__autoreleasing',而不是方法的參數。 – 2013-03-18 21:21:43

+0

@ RichardJ.RossIII謝謝,還補充說。 – 2013-03-18 21:23:21

5

作爲每the clang ARC spec,形式NSError **的方法參數(或更確切地說,一個指針到任何對象 - 對象)被隱含假定爲NSError * __autoreleasing *。這意味着該錯誤將在該方法中自動釋放。

至於呼叫站點,如果你用__autoreleasing變量調用它,就像你一樣,那麼一切都很好。其實我推薦這種模式。但是,如果您使用__strong變量調用它,它仍然可以工作。在這種情況下,編譯器會生成一個未命名的__autoreleasing臨時表,將該地址傳遞給該方法,然後在返回時它將臨時分配給__strong。所以,如果你有

NSError *foo; 
[bar callMethodWithError:&foo]; 

如果出參數是標記out,但這通常是如何工作的編譯器會將此一樣

NSError *foo; 
NSError * __autoreleasing tmp = foo; 
[bar callMethodWithError:&tmp]; 
foo = tmp; 

It's actually slightly more complicated than that

+0

這兩個答案都很好,並且都是回答者。 – QED 2013-03-19 04:29:54