天天看點

IOS SEL的了解與使用

   有很多人,認為block的推廣可取代代理設計模式,其實block并不能取代代理,代理的模式可以讓代碼邏輯性更強,更整潔,也會有更高的可讀性和可擴充性。相比之下,我覺得block更多的是取代了選擇器@selector。

   @selector是什麼?我們要首先明白sel,sel并不是一種對象類型,我們通過xcode的字型顔色就可以判斷出來,它是一個關鍵字,就像int,long一樣,它聲明了一種類型:類方法指針。其實就可以了解為一個函數指針。比如,我們生命一個叫mylog的函數指針:

<a href="http://my.oschina.net/u/2340880/blog/396367#">?</a>

1

2

3

4

5

6

7

<code>#import "viewcontroller.h"</code>

<code>@interface viewcontroller ()</code>

<code>{</code>

<code>    </code><code>sel mylog;</code>

<code>}</code>

<code>@end</code>

聲明出了這個指針,我們該如何給它傳遞這個函數呢?有兩種方式:

1、在編譯時,使用@selector來取得函數

現在,我們應該明白@selector是什麼了,它是一個編譯标示,我們通過它來取到相應函數。

8

9

10

11

12

13

14

15

16

17

18

19

<code>@implementation viewcontroller</code>

<code>- (</code><code>void</code><code>)viewdidload {</code>

<code>    </code><code>[super viewdidload];</code>

<code>    </code><code>// do any additional setup after loading the view, typically from a nib.</code>

<code>    </code><code>mylog = @selector(mylogl);</code>

<code>    </code><code>//通過performselector來執行方法</code>

<code>   </code><code>[self performselector:mylog];</code><code>//列印 “mylog”</code>

<code>   </code> 

<code>-(</code><code>void</code><code>)mylogl{</code>

<code>    </code><code>nslog(@</code><code>"mylog"</code><code>);</code>

2、在運作時,通過nsselectorfromstring方法來取到相應函數:

20

21

22

<code>    </code><code>mylog = nsselectorfromstring(@</code><code>"mylogn"</code><code>);</code>

<code>    </code><code>[self performselector:mylog];</code>

<code>-(</code><code>void</code><code>)mylogn{</code>

這兩種方式的差别在于,編譯時的方法如果沒有找到相應函數,xcode會報錯,而運作時的方法不會。

至于sel的應用,我相信最廣泛的便是target——action設計模式了。我們來簡單模拟一下系統button的工作原理:

我們先建立一個繼承于uibutton的類:

.h檔案:

<code>#import &lt;uikit/uikit.h&gt;</code>

<code>@interface mybutton : uibutton</code>

<code>-(</code><code>void</code><code>)addmytarget:(id)target action:(sel)action;</code>

.m檔案

<code>#import "mybutton.h"</code>

<code>@implementation mybutton</code>

<code>    </code><code>sel _action;</code>

<code>    </code><code>id _target;</code>

<code>-(</code><code>void</code><code>)addmytarget:(id)target action:(sel)action{</code>

<code>    </code><code>_target=target;</code>

<code>    </code><code>_action=action;</code>

<code>-(</code><code>void</code><code>)touchesbegan:(nsset *)touches withevent:(uievent *)event{</code>

<code>    </code><code>[_target performselector:_action];</code>

在外部:

<code>    </code><code>mybutton * btn = [[mybutton alloc]initwithframe:cgrectmake(100, 100, 60, 60)];</code>

<code>    </code><code>btn.backgroundcolor=[uicolor redcolor];</code>

<code>    </code><code>[btn addmytarget:self action:@selector(click)];</code>

<code>    </code><code>[self.view addsubview:btn];</code>

<code>-(</code><code>void</code><code>)click{</code>

<code>    </code><code>nslog(@</code><code>"點選了btn"</code><code>);</code>

當然,如果要調用參數,系統提供的預設參數不超過兩個,如果參數很多,一種是我們可以通過字典傳參,另一種方法比較複雜,在這裡先不讨論。

繼續閱讀