變數 in Objective-C
在 Objective C 中宣告變數的方式在不同的情況下會有使用不同的方式,這次想要跟大家分享關於宣告全域變數的部分。
先讓我們看看該如何宣告變數? 下面列出兩個方式來定義變數
NSString *aString = @"sample";
#define ASTRING @"MACRO_SAMPLE"
上面的兩個方式,分別是使用 NSString 以及 macro 分別宣告兩個不同的字串。兩種方式各有優缺,不過我們應該盡量使用第一種做法來宣告變數。至於 marco,通常都會使用在別的地方。
Why?
直接使用 Class 宣告的好處是:
- 變數的型別很清楚,即使命名不夠明確,你依然可以透過 Xcode 的 Auto-complete 快速的了解該變數的型別。
- 如果有重複宣告(即使在不同的 Class 中),Complie 會失敗,可以快速的修正錯誤。
- 可以使用 external 在 .h 中先進行宣告,而後在 .m 定義;而且還可以定義在不同 Class 中。
// Example for 3.
// in MySimple.hexternal 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 的時候。如果之後有機會分享建置流程再跟大家進一步分享這邊的內容。