2011-11-21 54 views
5

就良好的Objective-C編碼實踐而言,如果我創建一個沒有狀態的函數,最好是將它作爲某個類的靜態方法編寫,或者作爲C函數?無狀態靜態方法與Objective-C中的C函數的比較Objective-C

例如,我有一個特殊的文件路徑檢索方法,在繼續執行主要NSBundle之前檢查Caches目錄。我現在把它作爲一個靜態的方法在一個空的Utils類下面。這應該是一個C函數嗎?

我選擇使用靜態方法(現在)的原因是a)它與Objective-C語法一致,b)類有助於對方法進行分類。然而,我覺得自己在欺騙一點點,因爲我可以用這些無狀態的靜態方法輕鬆地填充我的Util類,並最終形成一個醜陋的「shell類」,其唯一目的是阻止它們。

你使用什麼約定?通過一些客觀的指標,一個比另一個「更好」嗎?謝謝!

回答

2

如果你能想到的現有類的,這可能成爲一個好方法,你可以通過一個Objective-C類注入你的方法進去。這將保留使用靜態方法的兩個原因,同時不會使用額外的類污染類空間。

例如:

@interface NSString (MyStringCategories) 
- (NSString*) myCoolMethod; 
@end 

// [StringCategories.m] 
#import "StringCategories.h" 

@implementation NSString (MyStringCategories) 
- (NSString*) myCoolMethod { 
    // do cool stuff here 
    return whateverYouLike; 
} 
@end 

現在,您可以發送myCoolMethod任何字符串。涼!

在你的特定情況下,它聽起來像一個NSBundle上的方法可能是一個合適的架構。別忘了,它可以是一個類方法,所以你不需要實例化任何東西來調用你的方法。

+0

是的,我儘可能經常嘗試。儘管如此,在這種情況下無法想到一個 - 它只搜索捆綁包,如果它沒有在緩存中找到該文件,並且它不是典型的pathForResource:的實例方法,所以(在我看來)它不是理想適合。 – Archagon

+0

因此,使它成爲一種類方法。我的觀點是,是不是不能想象一個適當的現有階級只是想象力的失敗?它可以是NSBundle,它可以是NSFileManager,也可以是NSString(因爲它處理路徑名),它可以是任何類,你可以直覺地感覺到它在正確的位置。 – matt

+0

+1對於類別。我個人認爲,課堂的目的是要立即實現的。不要將類用作名稱空間。所以如果你只有靜態方法,你應該考慮另一種方法。 – Macmade

1

這是一個相當難回答的問題,因爲對很多人來說,答案取決於他們的個人喜好和口味。我個人認爲,如果你有一個函數是一個函數,也就是說它與一個對象無關,它沒有內部狀態等。請讓它成爲一個函數,而不要試圖包裝你可能的任何東西一個對象,因爲你正在使用面向對象的語言,你可以。

爲了保持我的回答簡短,讓我指(IMO)相當不錯的書:

http://www.gotw.ca/publications/c++cs.htm

我知道,這是C++,但也有相當多的見解,可以與其他語言(特別是Objective-C和Objective-C++)共享,特別是從「類設計和繼承」部分。在那裏你會發現一個題爲「喜歡寫非成員非友人功能」的項目。 「非會員非友誼功能改進通過最小化依賴關係封裝[...]他們還打破了單一類[...] [和] [並]改進通用性[...]」。

我覺得這個項目裏有很多的道理。

1

如果沒有明確綁定它的類,那麼我使用一個函數。我還使用這些實用程序位的功能,因爲如果不使用或引用它們,它們可能會被剝離。在這方面,使用函數也是有幫助的,因爲鏈接錯誤比運行時錯誤要好(即使.m被意外地從構建中省略,或者如果被另一個外部更新的方法引用)。ObjC符號的一個問題是它們沒有被剝離,所以它們自然會攜帶大量的依賴關係 - 所有objc方法和類以及所需的類別方法必須存在於最終的二進制文件中。這對於非常小的程序或庫來說並不是問題,但它很快就會在中型/大型系統和庫中增加重量。

一切都不需要在@interface中聲明 - 尤其是對於大型系統,所有這些聲明都會將您的相互依賴關係變爲意大利麪條。與方法相比,函數更快,更小,可以通過編譯器或鏈接期間更好地優化,並且如果未引用,則可能會被剝離。

如果你需要多態的,它只是屬於在組織或方便類,則類或實例方法往往是一個更好的選擇。

我也儘量減少聲明出於同樣的原因的分類方法。當你使用函數時,你可以很容易地在你需要的地方編寫一個包裝器方法,並且獲得兩全其美的好處。