變數 in Objective-C

Green Chiu
iOS Nerd 🤓
Published in
3 min readApr 15, 2018

在 Objective C 中宣告變數的方式在不同的情況下會有使用不同的方式,這次想要跟大家分享關於宣告全域變數的部分。

先讓我們看看該如何宣告變數? 下面列出兩個方式來定義變數

NSString *aString = @"sample";
#define ASTRING @"MACRO_SAMPLE"

上面的兩個方式,分別是使用 NSString 以及 macro 分別宣告兩個不同的字串。兩種方式各有優缺,不過我們應該盡量使用第一種做法來宣告變數。至於 marco,通常都會使用在別的地方。

Why?

直接使用 Class 宣告的好處是:

  1. 變數的型別很清楚,即使命名不夠明確,你依然可以透過 Xcode 的 Auto-complete 快速的了解該變數的型別。
  2. 如果有重複宣告(即使在不同的 Class 中),Complie 會失敗,可以快速的修正錯誤。
  3. 可以使用 external 在 .h 中先進行宣告,而後在 .m 定義;而且還可以定義在不同 Class 中。
使用 Auto-complete 你可以快速了解到這個變數的型別
// Example for 3.
// in MySimple.h
external NSString *const MSSimpleNotification;@interface MySimple : NSObject
@end
// in MySimpleTask.mNSString *const MSSimpleNotification = @"SimpleNotification";
@implementation MySimpleTask
@end

上面的 simple code 中,用這樣的方式來宣告變數,可以避免繁雜的 import,就能讓 MySimpleTask 直接使用 MSSimpleNotification

為什麼不使用 marco 來定義變數?

除了上述說的 Auto-complete 並無法幫助你了解這個變數之外, marco 是可以重複定義的;你可以想像你有三個同事都叫吳恥仁,當有人跟你說你要找吳恥仁去達成某件事,如果他沒有特別交代是哪一個,你會知道該找誰嗎?更何況,你還能使用 #undef 來取消之前宣告的 macro 。

相比起來,使用 Class 直接宣告的變數讓你寫出來的程式更容易被其他人閱讀跟維護。

那什麼時候使用 macro ?在重複使用簡單的 method/判斷式上,你可以將它定義成 marco ,以便快速地使用。

#define MAKE_FAST_ERROR(error_code, error_desc) ( [NSError errorWithDomain: .... ] )
#define INVALIDETE_TIME( time ) if (time) { \
[time invalidate]; \
time = nil; }
#define DEGREE_TO_PI ...

上面的第一個例子,我定義了一個只需要提供 error code 以及 description 就能快速產生 NSError 的 macro,在實作錯誤回饋的時候,就能省下不少時間。

除了這樣的使用方式之外,我們也常常在專案中使用 #ifdef 來判斷是否定義了某些 marco ,來確定/保護某些功能只出現在特定的版本中之。

當然,依照不同的情境,還是會有使用 macro 來定義參數,尤其是在使用 Preprocessor Marcos 的時候。如果之後有機會分享建置流程再跟大家進一步分享這邊的內容。

--

--

Green Chiu
iOS Nerd 🤓

Do something to improve myself and try everything I like.