2013-01-23 97 views
8

我有這樣的方法:什麼是從autoreleasepool塊內設置NSError outparam的正確方法?

- (void)processAThing:(id)thing error:(NSError * __autoreleasing *)error 
{ 
    @autoreleasepool { 

      // Start processing. 

      // Find some partway through error.. 
      if (error) { 
       *error = [NSError errorWithDomain...]; 
       return NO; 
      } 

      // More processing. 
    } 
} 

這是破碎和崩潰,因爲NSError會被自動釋放,並返回,這時,池排出,使主叫方獲得的東西現在是僞造的。

我知道我可以大大地重新設計方法,所以我收集autorelease塊之外的所有錯誤情況,但我想了解在這種情況下是否有正確的方式來處理錯誤對象。我不能在池塊之​​外分配/初始化一個推測的NSError,因爲域和代碼屬性是隻讀的(我仍然認爲當方法返回時引用會消失)。

它解決了問題,如果我改變了方法聲明如下:

- (void)processAThing:(id)thing error:(NSError * __strong *)error 

但後來我需要在一個非標準的方式調用點大驚小怪左右,這似乎令人震驚,使主叫方支付價格爲我的內部autoreleasepool。

有什麼想法?謝謝。

+0

將簽名更改爲「(NSError * __strong *)錯誤」實際上似乎是對我來說合理的選擇。 – Poulsbo

回答

7

我自己也有這個問題。在這種情況下,我認爲你只需要在@autoreleasepool之前聲明一個新的強參考,並將該方法參數設置爲緊接在該臨時參考的@autoreleasepool塊之後。

- (void)processAThing:(id)thing error:(NSError * __autoreleasing *)error { 
    __strong NSError *errOut = nil; 
    @autoreleasepool { 
    // do your stuff and set errOut instead of error 
    } 
    if (error) { 
    *error = errOut; 
    } 
} 

(輸入瀏覽器,通過編譯器不要錯誤校驗)

至於你提前返回,我想你將不得不使用一個跳轉標籤(即使它不漂亮)。

+0

你不需要寫'__strong'。這是默認 – newacct

+1

是的,我只是爲了澄清。 –

+0

謝謝埃裏克。聽起來像沒有其他明顯的模式可以使用,除非最小化autorelease塊的範圍並在其外部設置outparam。 –

相關問題