2013-06-01 53 views
4

我使用Xcode的重構能力開始(編輯>重構>提取),發現Xcode中提供提取方法功能的Objective-C:何時使用功能VS方法

我讀過hereelsewhere關於兩者之間的差異,並明白,一個方法連接到類而功能不是。所以我不在尋找定義。

假設不涉及任何參數,什麼時候使用一個而不使用另一個?我明白,如果事情不是真的關於類,那麼它可能是一個函數,但是再次,這只是關於定義。我正在尋找好的用例。

在我個人的案例中,我試圖從AppDelegate的applicationDidEnterBackground中重構一些代碼。由於它是進入後臺處理事件的唯一地方,清理代碼的唯一方法是將子例程提取到..以及函數中。但他們會在AppDelegate.m內,所以他們不是方法?

嗯..

+0

我用一種功能,當我的代碼sortedArrayUsingFunction。 –

回答

2

您使用的功能,當你有一個,好,功能;-)你知道的定義:一個方法有一個隱含參數self並且可以訪問實例使用它的變量;一個函數沒有隱式參數 - 它需要的所有東西都必須傳入。

如果您正在重構部分更大的方法,那部分不訪問實例變量,並且您不重構它,以便子類可以覆蓋它,然後讓Xcode爲您構建函數。完成後,將它加入static,這樣它對班級是私人的。

在這樣做的時候,你什麼都不會丟失,並且明確表示這段代碼是一個函數 - 它不會改變對象的狀態。

選取函數和方法之間當然沒有硬線,它是一個模糊的邊界。如果一段代碼只是訪問一個或兩個實例變量但不更新它們,那麼您可以選擇一個函數 - 再次明確指出對象狀態未被修改。但是你不想在參數中傳遞大量的實例變量,這很難閱讀(並且效率低下)。

使用函數可以很好,在Objective-C中這樣做肯定不錯。功能

8

就個人而言,我只用功能,當且僅當,以下兩個要求得到滿足:

  1. 我用它如此頻繁地在給定類中,或在整個項目,這是值得推廣的。
  2. 它沒有任何副作用或上下文依賴關係(沒有一個void *context混亂)。

在我看來,C風格的函數只能作爲最後的手段,或者在這種應用程序中真正需要功能行爲的情況下。事件處理既是特定於應用程序的,也是上下文敏感的,所以最好將它放在一邊,專注於重構常見模式。

+0

當你談論離開事件處理時,你是指applicationDidEnterBackground嗎? –

+0

@arigold我指的是任何方法。事件處理依賴於Responder Chain,這是一個非常「Objective-C」的概念,應該像這樣降級。 – CodaFi

2

類的方法通常需要訪問連接到該類的實例變量。 Objective-C中的函數沒有連接到類,因此不能訪問類的任何非公共成員變量。

考慮包含成員變量_memberVar的類KNode。

@interface KNode : NSObject { 
    int _memberVar; 
} 

@end 

此類的任何方法都可以訪問和更改成員變量,但任何舊函數都不能,因爲它是私有的。

@implementation KNode 

- (void)modify { 
    _memberVar = 10; 
} 

@end 

以下功能將無法正常工作

void modify(KNode * node) { 
    _memberVar = 10; 
} 
2

兩個小但有意義的優點:

  • 它們可以是內部的,只有通過標記他們static,或 __attribute__((visibility("hidden"))),這是供框架開發
  • 它們可以被內聯很有幫助。例如,我用這個模式來快速懶隊列創建:

    static inline dispatch_queue_t sharedQueue() { 
        static dispatch_queue_t queue; 
        static dispatch_once_t once; 
        dispatch_once(&once, ^{ 
         queue = dispatch_queue_create("foo", 0); 
        }); 
        return queue; 
    }