iOS 學習筆記之開發技巧weakself宏

前言

開發中尤其是純代碼開發界面的時候一些重複代碼不斷的輸入,着實讓人覺得很浪費時間,但是用別的方式可行性不高,所以用了codesnippet完成自動補全,大大地提高了開發的效率,爲我們節省不少時間。

本篇旨在通過一個weakself的宏定義爲大家提供一些思路。

原文地址:iOS開發小技巧之--weakself宏

正文

一、weak宏定義進化史


我們都知道在防止如block的循環引用時,會使用__weak關鍵字做如下定義:

__weak typeof(self) weakSelf = self;

後來,爲了方便,不用每次都要寫這樣一句固定代碼,我們定義了宏

#define WeakSelf __weak typeof(self) weakSelf = self;

之後,我們可以比較方便的在需要的地方:

WeakSelf;
...
[weakSelf doSomething];

再後來,我們發現不止self需要使用weak,可能有部分變量也需要weak,於是我們的宏繼續進化,不僅僅只支持self:

#define WeakObj(o) __weak typeof(o) o##Weak = o;

這樣,後續對需要使用weak的對象,只要寫一句WeakObj(obj)即可使用objWeak變量了(PS:發現沒有,這裏生成的變量名其實是objWeak,並不是weakObj,原因見文章末的注1)

再後來,我們發現了一些小技巧,可以讓我們的這個宏看起來更原生一些,我們添加了@符號在前面:

#define WeakObj(o) autoreleasepool{} __weak typeof(o) o##Weak = o;

使用上看起來是這樣

@WeakObj(self);
...
[selfWeak doSomething];

是不是感覺挺高大上的?
這裏是利用了@autoreleasepool{}這個系統的關鍵字來實現的,其實還可以利用@try{}@finally{}這個也可以達到相同的效果,比如:

#define WeakObj(o) try{}@finally{} __weak typeof(o) o##Weak = o;

這部分空的@try或者空的@autoreleasepool會在編譯時被優化掉,不必擔心性能問題。
相應的strong宏如下:

#define StrongObj(o) autoreleasepool{} __strong typeof(o) o = o##Weak;

使用例子如下:

@WeakObj(self);
[var setBlock:^{
    @StrongObj(self);
    [self doSomething];
}];

是不是很簡約,有rac類似宏的效果。

二、結合codesnippet 完成自動補全功能


至此,我們的宏已經可以用了,但是實際使用中,出現了一個很尷尬的問題,就是代碼自動補全,@W並不能自動提示出該宏,所以每次都是很尷尬的先利用提示,寫完WeakObj(obj),然後光標移動到前面去打上一個@符號。
這種事情怎麼能忍受?
還好我們還有利器,XcodeCodeSnippet,任意方法內,寫一句代碼

@WeakObj(<#obj#>);

拖到Xcode的CodeSnippet區域,快捷鍵設置爲@WeakObj即可。

 

至此,愉快的使用@W即可自動補全出該宏了。。

三、補充


最後,揭曉爲什麼該宏生成的變量名是objWeak

  1. 使用時,如果開發者習慣性的要打出 [self doSomething]時,當他輸入self時,自動補全出來的部分能看到還有selfWeak可供選擇,算是一種提醒方式。
  2. 如果weak前置,當然也可以,生成的會是weakobj這樣的變量名,只需要把宏中o##Weak 換成weak##o

好了,這篇文章希望對一些人有些啓發或幫助。

Xcode代碼塊轉移備份同步(CodeSnippets)代碼塊路徑
代碼塊的保存路徑;
~/Library/Developer/Xcode/UserData/CodeSnippets

參考文章:
@weakify和@strongify實現分析

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章