[iOS] Macro管理code的情境

在自己的專案裡面看到許多重複的程式碼,為了易讀、好管理,嘗試用macro重寫,以下稍微介紹我使用的情境,和macro的使用法。

情境

我要管理追蹤某個autolayout的更新,因此需要三種property:一個subview,一個subview的尺寸的constraint,一個boolean值作為flag判斷有沒有更新constraint。

所以為了追蹤一個view,寫起來大概是這樣:

@property (nonatomic, weak) IBOutlet UIView *subview;
@property (nonatomic, weak) IBOutlet NSLayoutConstraint *subviewConstraint;
@property (nonatomic, getter=isSubviewConstraintDidChanged) BOOL subviewConstraintDidChanged;

如果你有很多個類似這樣管理的subview,那其實就會有很多行的重複property,程式碼會不好讀。

你可以使用macro,進行改寫:

#define Properties(NAME, name) \
@property (weak, nonatomic) IBOutlet UIView *name; \
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *name ## Constraint; \
@property (nonatomic, getter=is ## Name ## ConstraintDidChanged) BOOL name ## ConstraintDidChanged; \

你定義了一個macro叫做Properties,收兩個參數NAME和name,在這邊我會用來輸入只有首字母大小寫不同的subvew名稱,讓macro去合成我要的code。

然後你就可以用這個Macro去追蹤好幾個View了:

Properties(MySubview, mySubview)
Properties(SecondSubview, secondSubview)
Properties(ThirdSubview, thirdSubview)

總共會產生九個properties。

一至性的物件命名規則,有助於有效率的使用macro去管理重複性的code,同樣的一個物件,名稱完整的用在不同地方,你就可以用macro去統整起來。

Concatenation

這邊介紹一下##的用法,這在macro是連接tokens然後做出新的token。比方說以下這種寫法:

name ## Constraint

就是把你輸入的參數name和Constraint連接起來,比方說你輸入mySubview,編譯器看到的是:

mySubviewConstraint

那些空格和##,都會被刪除。

注意 * 是沒辦法也不需要用##去連接的,所以直接寫就好(參考前面的code)。

Show your support

Clapping shows how much you appreciated SC Tuan’s story.