詳解蘋(píng)果的黑魔法 – KVO 的奧秘

在iOS開(kāi)發(fā)中,蘋(píng)果提供了許多機(jī)制給我們進(jìn)行回調(diào)。KVO(key-value-observing)是一種十分有趣的回調(diào)機(jī)制总滩,在某個(gè)對(duì)象注冊(cè)監(jiān)聽(tīng)者后俺驶,在被監(jiān)聽(tīng)的對(duì)象發(fā)生改變時(shí)幸逆,對(duì)象會(huì)發(fā)送一個(gè)通知給監(jiān)聽(tīng)者,以便監(jiān)聽(tīng)者執(zhí)行回調(diào)操作暮现。最常見(jiàn)的KVO運(yùn)用是監(jiān)聽(tīng)scrollView的contentOffset屬性还绘,來(lái)完成用戶(hù)滾動(dòng)時(shí)動(dòng)態(tài)改變某些控件的屬性實(shí)現(xiàn)效果,包括漸變導(dǎo)航欄栖袋、下拉刷新控件等效果拍顷。
http://jbcdn2.b0.upaiyun.com/2015/12/36a1f0f0ac4af124dbdb65895b2d0fc9.gif

使用

KVO的使用非常簡(jiǎn)單,使用KVO的要求是對(duì)象必須能支持kvc機(jī)制——所有NSObject的子類(lèi)都支持這個(gè)機(jī)制塘幅。拿上面的漸變導(dǎo)航欄做昔案,我們?yōu)閠ableView添加了一個(gè)監(jiān)聽(tīng)者controller,在我們滑動(dòng)列表的時(shí)候电媳,會(huì)計(jì)算當(dāng)前列表的滾動(dòng)偏移量踏揣,然后改變導(dǎo)航欄的背景色透明度。

<pre>//添加監(jiān)聽(tīng)者
[self.tableView addObserver: self forKeyPath: @"contentOffset" options: NSKeyValueObservingOptionNew context: nil];
/**

  • 監(jiān)聽(tīng)屬性值發(fā)生改變時(shí)回調(diào)
    */
  • (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
    CGFloat offset = self.tableView.contentOffset.y;
    CGFloat delta = offset / 64.f + 1.f;
    delta = MAX(0, delta);
    [self alphaNavController].barAlpha = MIN(1, delta);
    }
    </pre>

毫無(wú)疑問(wèn)匾乓,kvo是一種非常便捷的回調(diào)方式捞稿,但是編譯器是怎么完成監(jiān)聽(tīng)這個(gè)任務(wù)的呢?先來(lái)看看蘋(píng)果文檔對(duì)于KVO的實(shí)現(xiàn)描述

Automatic key-value observing is implemented using a technique called isa-swizzling… When an observer is registered for an attribute of an object the isa pointer of the observed object is modified, pointing to an intermediate class rather than at the true class ..
簡(jiǎn)要的來(lái)說(shuō),在我們對(duì)某個(gè)對(duì)象完成監(jiān)聽(tīng)的注冊(cè)后娱局,編譯器會(huì)修改監(jiān)聽(tīng)對(duì)象(上文中的tableView)的isa指針彰亥,讓這個(gè)指針指向一個(gè)新生成的中間類(lèi)。從某個(gè)意義上來(lái)說(shuō)铃辖,這是一場(chǎng)騙局剩愧。
<pre>typedef struct objc_class *Class;
typedef struct objc_object {
Class isa;
} *id</pre>

KVO使用三步走:

(1)注冊(cè)成為觀察者

(2)觀察者定義KVO的回調(diào)

(3)移除觀察者

來(lái)點(diǎn)實(shí)際的,還得上代碼:

KVOClass接口:
<pre>

import

@interface KVOClass : NSObject
@property(strong,nonatomic) NSString * name;
@end</pre>
KVOClass實(shí)現(xiàn)
<pre>#import "KVOClass.h"

@implementation KVOClass
//在init注冊(cè)觀察者
-(id) init
{
if (self = [super init]) {
[self addObserver:self
forKeyPath:@"name"
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
context:@"name"];
}
return self;
}

//重寫(xiě)觀察方

  • (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
    if (context == @"name") {
    NSLog(@"name被改變啦娇斩!");
    } else {
    [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
    }
    //移除觀察者
    -(void) dealloc
    {
    [self removeObserver:self forKeyPath:@"name"];
    [super dealloc];
    }
    @end</pre>
    待續(xù)仁卷。。犬第。锦积。。歉嗓。丰介。。鉴分。哮幢。。志珍。橙垢。。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末伦糯,一起剝皮案震驚了整個(gè)濱河市柜某,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌敛纲,老刑警劉巖喂击,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異淤翔,居然都是意外死亡翰绊,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)旁壮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)辞做,“玉大人,你說(shuō)我怎么就攤上這事寡具〕用” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵童叠,是天一觀的道長(zhǎng)框喳。 經(jīng)常有香客問(wèn)我课幕,道長(zhǎng),這世上最難降的妖魔是什么五垮? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任乍惊,我火速辦了婚禮,結(jié)果婚禮上放仗,老公的妹妹穿的比我還像新娘润绎。我一直安慰自己,他們只是感情好诞挨,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布莉撇。 她就那樣靜靜地躺著,像睡著了一般惶傻。 火紅的嫁衣襯著肌膚如雪棍郎。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,457評(píng)論 1 311
  • 那天银室,我揣著相機(jī)與錄音涂佃,去河邊找鬼。 笑死蜈敢,一個(gè)胖子當(dāng)著我的面吹牛辜荠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播抓狭,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼伯病,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了辐宾?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤膨蛮,失蹤者是張志新(化名)和其女友劉穎叠纹,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體敞葛,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡誉察,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了惹谐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片持偏。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖氨肌,靈堂內(nèi)的尸體忽然破棺而出鸿秆,到底是詐尸還是另有隱情,我是刑警寧澤怎囚,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布卿叽,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏考婴。R本人自食惡果不足惜贩虾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望沥阱。 院中可真熱鬧缎罢,春花似錦、人聲如沸考杉。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)奔则。三九已至蛮寂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間易茬,已是汗流浹背酬蹋。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留抽莱,地道東北人范抓。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像食铐,于是被迫代替她去往敵國(guó)和親匕垫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容

  • 在iOS開(kāi)發(fā)中虐呻,蘋(píng)果提供了許多機(jī)制給我們進(jìn)行回調(diào)象泵。KVO(key-value-observing)是一種十分有趣的...
    流沙3333閱讀 359評(píng)論 0 0
  • 原文鏈接 基于觀察者設(shè)計(jì)模式,蘋(píng)果實(shí)現(xiàn)了notification和kvo兩套監(jiān)聽(tīng)機(jī)制斟叼,兩者都實(shí)現(xiàn)了一對(duì)多的監(jiān)聽(tīng)支持...
    sindri的小巢閱讀 48,303評(píng)論 48 222
  • 序言在iOS開(kāi)發(fā)中偶惠,蘋(píng)果提供了許多機(jī)制給我們進(jìn)行回調(diào)。KVO(key-value-observing)是一種十分有...
    陌尚煙雨遙閱讀 484評(píng)論 0 0
  • FBKVOController是一個(gè)簡(jiǎn)單易用的鍵值觀察框架朗涩,KVOController 對(duì)于 Cocoa 中 KV...
    我有小尾巴快看閱讀 1,389評(píng)論 0 0
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉忽孽,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,726評(píng)論 0 9