iOS開發中 selector的理解與應用

2021-07-10 20:01:44 字數 2789 閱讀 8267

@selector

@selector 是什麼?

1一種型別 sel

2代表你要傳送的訊息(方法), 跟字串有點像, 也可以互轉.: nsselectorfromstring() / nsselectorfromstring()

3可以理解為類似函式指標的東西--是能讓objective-c動態呼叫方法的玩意.--是 object-c 的動態後繫結技術 可以通過字串 訪問的函式指標

4其實就是訊息響應函式---選乙個訊息響應的函式位址給你的action

5@selector(function_name) 即取得乙個function的id

objc_msg*** 系列函式是全域性的

performselector 是nsobject成員方法,ms效果差不多

關於objc_msgsend & performselector系列函式的問題。

1。objc_msgsend:

書上說這個函式是oc編譯器在編譯的時候,遇到類似[object foo]的寫法時,就會把相應oc的語法轉成c的objc_msgsend函式了。還有相應的objc_msgsendsuper

2。關於performselector系列:

performselector, performselector:withdelay:, performselector:withobj:withdelay, ***...

除了第乙個,後面幾個都可以指定乙個延遲時間,然後就把selector放到當前執行緒的runloop中等待呼叫。從方法名上看,感覺performselector == performselector:withdelay系列中,delay為0的情況。

我的問題是:

1。objc_msgsend這個函式是直接由[object foo]轉過來的嗎? 也就是說,中間不會轉成performselector吧?objc_msgsend是同步的嗎?

2。performselector:withdelay:這個是非同步的了,放進runloop中,那如果performselector和performselector:withdelay(delay為0時)一樣的話, 那performselector也是非同步的嗎?也要進runloop嗎?

答:1、是的,不要performselector了,直接objc_msgsend。事實上,這個是oc編譯時就轉好的,也就是oc編譯的時候就把物件呼叫轉成函式的call了

2、是的,delay為0也進runloop,這樣做的好處是可以不阻住當前呼叫performselector:withdelay:的方法的執行

怎樣證實上邊的答案沒有問題?

很簡單,寫幾個測試**,然後打斷點一跑,在執行時看呼叫棧。

觀察程式執行最好的方法總是偵錯程式~

respondstoselector

3、delegate屬性使用assign的原因。

迴圈引用

所有的引用計數系統,都存在迴圈應用的問題。例如下面的引用關係:

物件a建立並引用到了物件b.

物件b建立並引用到了物件c.

物件c建立並引用到了物件b.

這時候b和c的引用計數分別是2和1。當a不再使用b,呼叫release釋放對b的所有權,因為c還引用了b,所以b的引用計數為1,b不會被釋放。b不釋放,c的引用計數就是1,c也不會被釋放。從此,b和c永遠留在記憶體中。

這種情況,必須打斷迴圈引用,通過其他規則來維護引用關係。比如,我們常見的delegate往往是assign方式的屬性而不是retain方式的屬性,賦值不會增加引用計數,就是為了防止delegation兩端產生不必要的迴圈引用。如果乙個uitableviewcontroller 物件a通過retain獲取了uitableview物件b的所有權,這個uitableview物件b的delegate又是a,如果這個delegate是retain方式的,那基本上就沒有機會釋放這兩個物件了。自己在設計使用delegate模式時,也要注意這點。

因為迴圈引用而產生的記憶體洩露也是instrument無法發現的,所以要特別小心。

4、delegate屬性使用assign的原因。

還有一些用法會讓系統擁有物件的所有權。比如nsobject 的performselector:withobject:afterdelay 。如果有必要,需要顯示的呼叫cancelpreviousperformrequestswithtarget:selector:object: ,否則有可能產生記憶體洩露。

iphone開發中,動態呼叫類和方法:

nsclassfromstring

nsselectorfromstring

正常來說,

id myobj = [[nsclassfromstring(@"myspecialclass") alloc] init];

和id myobj = [[myspecialclass alloc] init];

是一樣的。但是,如果你的程式中並不存在myspecialclass這個類,下面的寫法會出錯,而上面的寫法只是返回乙個空物件而已。

因此,在某些情況下,可以使用nsclassfromstring來進行你不確定的類的初始化。

比如在iphone中,nstask可能就會出現這種情況,所以在你需要使用nstask時,最好使用:

[[nsclassfromstring(@"nstask") .....]]

而不要直接使用[nstask ...]這種寫法。

nsclassfromstring的好處是:

1 弱化連線,因此並不會把沒有的framework也link到程式中。

2 不需要使用import,因為類是動態載入的,只要存在就可以載入。

for (int c=0; c<[classnames count]; c++)

}

iOS開發之 Selector引數的傳遞

比如 nsmutabledictionary dic numutabledictionary alloc init dic setvalue haha forkey test nstimer scheduledtimerwithtimeintervatal 2.0 target self selec...

在iOS開發中告別未定義selector

objc和c 同為由c語言衍生出的oop語言,但他們實現oop的方式並不相同 在c 中,物件與方法在編譯器繫結 而在objc中,稱 方法 一詞為 訊息 在程式執行時向物件傳送訊息,即執行期繫結。兩種方式各有優劣,c 注重效能,objc注重靈活。然而執行期繫結給開發帶來問題 程式設計時拼寫錯了方法名,...

Swift Swift中Selector的變化

swift中selector變化 2.2 之前,使用字串作為方法名稱 無引數btn.addtarget self,action selector buttonpress forcontrolevents touchupinside 有引數 btn.addtarget self,action sele...