ios UIControl類中的addTarget: action: forControlEvents: 方法認(rèn)識(shí)

addTarget: action: forControlEvents:在我們開(kāi)發(fā)中最為經(jīng)常用的方法,尤其是UIButton。這個(gè)方法的最底層為UIControl類,在我們開(kāi)發(fā)中用到它的,都是它子類。

UIControl類

UIControl是控件類的基類,它是一個(gè)抽象基類,我們不能直接使用UIControl類來(lái)實(shí)例化控件,它只是為控件子類定義一些通用的接口,并提供一些基礎(chǔ)實(shí)現(xiàn),以在事件發(fā)生時(shí),預(yù)處理這些消息并將它們發(fā)送到指定目標(biāo)對(duì)象上。

UIControl的是針對(duì)單點(diǎn)觸摸,由于UIControl本身是視圖,所以它實(shí)際上也繼承了UIResponse。

為了判斷當(dāng)前對(duì)象是否正在追蹤觸摸操作,UIControl定義了一個(gè)tracking屬性。該值如果為YES,則表明正在追蹤。這對(duì)于我們是更加方便了,不需要自己再去額外定義一個(gè)變量來(lái)做處理。

UIControl的其它具體屬性和特性可以觀看這篇文章:http://www.cocoachina.com/ios/20160111/14932.html

這里主要說(shuō)一下UIControl的Target-Action機(jī)制
Target-action是一種設(shè)計(jì)模式,直譯過(guò)來(lái)就是目標(biāo)-行為。當(dāng)我們通過(guò)代碼為一個(gè)按鈕添加一個(gè)點(diǎn)擊事件時(shí),通常是如下處理:

[button addTarget:self action:@selector(tapButton:) forControlEvents:UIControlEventTouchUpInside];

也就是說(shuō),當(dāng)按鈕的點(diǎn)擊事件發(fā)生時(shí),會(huì)將消息發(fā)送到target(此處即為self對(duì)象),并由target對(duì)象的tapButton:方法來(lái)處理相應(yīng)的事件。這里的target的對(duì)象是一個(gè)在內(nèi)存中的,tapButton:的執(zhí)行方法也是對(duì)象還存在。如果這兩者不存在會(huì)出現(xiàn)崩潰現(xiàn)象。
例子:
我創(chuàng)建一個(gè)對(duì)象A是繼承NSObject,在這個(gè)對(duì)象中寫(xiě)一個(gè)方法用來(lái)做執(zhí)行的。這是我在UIControl分類B的一個(gè)方法中創(chuàng)建A,接著寫(xiě)Target-action,tapButton:的方法是A對(duì)象中方法。所有的都準(zhǔn)備好了,執(zhí)行的時(shí)候出現(xiàn)了崩潰。
代碼:

- (void)clickOperation:(void (^) (void))perform style:(UIControlEvents)style {
    TYImplementCallback *back = [TYImplementCallback createImpLementCallback:perform];
    [self addTarget:back action:@selector(callback) forControlEvents:style];
}

為什么會(huì)出現(xiàn)這樣的情況了。這是因?yàn)槲覍?duì)內(nèi)存這個(gè)概論的認(rèn)識(shí)不夠深刻。繼承NSObject的類創(chuàng)建的時(shí)候不用像其它可視化控件一樣有一個(gè)add過(guò)程,這個(gè)add過(guò)程就是將對(duì)象的內(nèi)存加入到堆中。而NSObject沒(méi)有add所以它內(nèi)存一直在棧中,只要一離開(kāi)}這個(gè)對(duì)象的內(nèi)存就沒(méi)有了,而我們操作點(diǎn)擊事件是在出了括號(hào)才執(zhí)行的。所以會(huì)導(dǎo)致我們的程序就會(huì)崩潰。

解決這個(gè)方法還有就是

//這里的作用聲明全局對(duì)象,它內(nèi)存是放在這個(gè)大的對(duì)象堆中。是跟隨大的對(duì)象內(nèi)存消失而消失的。
@interface UIControl()

@end

中寫(xiě)一個(gè)全局聲明的對(duì)象,然后在創(chuàng)建NSObject的類后,就這個(gè)對(duì)象賦值給我們剛才聲明的全局對(duì)象。這樣就能保證我們的NSObject對(duì)象不會(huì)出了括號(hào)就消失了。在分類當(dāng)中沒(méi)有set方法和get方法,也沒(méi)有實(shí)例化屬性發(fā)功能。我們可以通過(guò)runtime機(jī)制進(jìn)行實(shí)現(xiàn)。
代碼:

- (TYImplementCallback *)back{
    return objc_getAssociatedObject(self, &backKey);
}

- (void)setBack:(TYImplementCallback *)back {
    objc_setAssociatedObject(self, &backKey, back, OBJC_ASSOCIATION_RETAIN);
}

- (void)clickOperation:(void (^) (void))perform style:(UIControlEvents)style {
    self.back = [TYImplementCallback createImpLementCallback:perform];
    [self addTarget:self.back action:@selector(callback) forControlEvents:style];
}

在我們的開(kāi)發(fā)現(xiàn)在雖然使用了ARC來(lái)進(jìn)行內(nèi)存管理,但是我們還是要對(duì)內(nèi)存管理要有了解。什么樣的情況是在堆中,什么樣的情況是在棧中。我這兩天的錯(cuò)誤就是對(duì)內(nèi)存的不太深入的了解。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時(shí)...
    歐辰_OSR閱讀 30,229評(píng)論 8 265
  • *面試心聲:其實(shí)這些題本人都沒(méi)怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個(gè)offer,總結(jié)起來(lái)就是把...
    Dove_iOS閱讀 27,618評(píng)論 30 472
  • 在開(kāi)發(fā)過(guò)程中,大家或多或少的都會(huì)碰到令人頭疼的手勢(shì)沖突問(wèn)題,正好前兩天碰到一個(gè)類似的bug,于是借著這個(gè)機(jī)會(huì)了解了...
    閆仕偉閱讀 5,681評(píng)論 2 23
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,650評(píng)論 1 32
  • 無(wú)論何時(shí),都請(qǐng)嚴(yán)格自律才好。 自律的人如果堅(jiān)定的走下去, 必然是可怕的。 時(shí)刻準(zhǔn)備著已知事物的到來(lái)也是很不容易的,...
    子誓不染閱讀 229評(píng)論 0 0

友情鏈接更多精彩內(nèi)容