返回一個自動釋放對象是一種抽象的形式 - 開發人員的方便,所以他/她不必考慮返回對象的引用計數 - 因此會導致更少的特定錯誤類別(儘管您也可以說autorelease池引入了新的類別的錯誤或複雜性)。它可以真正簡化客戶端代碼,但是,可能會有性能問題。當不需要進行參考操作時,它也可以用作抽象優化 - 考慮對象何時持有返回的實例並且不需要進行保留或複製。儘管鏈接語句可以被過度使用,但這種做法對於鏈接語句也很方便。
此外,確定引用計數錯誤的靜態分析器對於這些庫和程序中的一些來說是相對較新的。 Autorelease池在ARC之前,對objc對象的引用計數進行多年的靜態分析 - 確保您的引用計數正確,現在使用這些工具更簡單。他們能夠檢測到許多錯誤。
當然,如果您喜歡簡單的返回自動釋放對象 - 使用ARC,您可以返回更少的自動釋放對象,而無需引入抽象的autorelease池錯誤。
使用統一的所有權語義也簡化了程序。如果抽象選擇器或選擇器集合總是使用相同的語義返回,那麼它確實可以簡化一些通用形式。例如 - 如果傳遞給performSelector:
的一組選擇器具有不同的所有權返回語義,則會增加很多複雜性。如此統一的所有權歸還可以真正簡化一些更「通用」的實現。
性能:引用計數操作(保留/釋放)可能相當重要 - 尤其是如果您習慣於在較低級別工作。但是,當前的自動釋放池實現速度非常快。它們最近被更新了,並且比以前更快。編譯器和運行庫使用幾個特殊的快捷鍵來降低這些成本。保持autorelease池的大小也是一個好主意 - 特別是在移動設備上。創建一個autorelease池非常快。實際上,您可能會從自動釋放操作本身增加零個百分點到幾個百分點(即消耗的時間比objc_msgSend
+變體少得多)。有些測試甚至跑得快一點。這不是許多人將從中獲得的優化。在典型情況下,它不會成爲低掛果實,而且在真實計劃中衡量這種變化的效果和地點實際上相對困難 - 基於我在bbum提到下面的變化之後所做的一些測試。所以測試範圍有限,但MRC和ARC似乎更好/更快。
因此,如果您正在執行自己的引用計數操作,很多情況都歸結於您想要承擔的責任級別。對於大多數人來說,它不應該改變他們的寫作方式。我認爲本地化內存問題,更多確定性的對象破壞,以及更可預測的堆大小是人們可能喜歡的主要原因如果您在現代系統上運行,則返回「擁有」(+1)引用計數。即使如此,在很多情況下,運行時和編譯器都會爲您減少這個數量(請參閱bbum的答案+1)。儘管自動釋放池大約一樣快,但我現在不打算比現在更多地使用它們 - 所以仍然有合理的理由儘量減少使用它們,但原因正在減少。
總是有機會忘記釋放它。在代碼中將分配和釋放分離太遠是潛在的錯誤來源。特別是當你在一個函數中分配一些東西作爲返回對象時。 – nhahtdh
這是一個所有權問題。在情況1中,自動釋放的對象由方法返回,因爲它可能屬於類或框架,而不是調用者。 – CodaFi