ios中對KVO、KVC的一些理解

來源:互聯網
上載者:User

Key-Value Observing (簡寫為KVO):當指定的對象的屬性被修改了,允許對象接受到通知的機制。每次指定的被觀察對象的屬性被修改的時候,KVO都會自動的去通知相應的觀察者,相當於設計模式中的觀察者模式。

KVO的優點:
當有屬性改變,KVO會提供自動的訊息通知。這樣的架構有很多好處。首先,開發人員不需要自己去實現這樣的方案:每次屬性改變了就發送訊息通知。這是KVO 機制提供的最大的優點。因為這個方案已經被明確定義,獲得架構級支援,可以方便地採用。開發人員不需要添加任何代碼,不需要設計自己的觀察者模型,直接可 以在工程裡使用。其次,KVO的架構非常的強大,可以很容易的支援多個觀察者觀察同一個屬性,以及相關的值。

下面我們寫個簡單的demo,如何使用KVO

首先定義一個類,聲明兩個屬性,name跟pid;

@interface DataModel : NSObject{            NSString *name;    NSString *pid;    }
在controller裡

- (void)viewDidLoad{        [super viewDidLoad];            dm=[[DataModel alloc] init];            [dm setValue:@"daren" forKey:@"name"];    [dm setValue:@"1" forKey:@"pid"];        //註冊成為觀察者 選項參數指定了發送變更通知時提供給觀察者的資訊。使用NSKeyValueObservingOptionOld選項可以將初始對象值以變更字典中的一個項的形式提供給觀察者。指定NSKeyValueObservingOptionNew選項可以將新的值以一個項的形式添加至變更字典。    [dm addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];        testLabel=[[UILabel alloc] init];    [testLabel setFrame:CGRectMake(20, 20, 100, 30)];    [testLabel setBackgroundColor:[UIColor clearColor]];    [testLabel setTintColor:[UIColor blackColor]];        [testLabel setText:[dm valueForKey:@"name"]];        [self.view addSubview:testLabel];                UIButton *testButton=[UIButton buttonWithType:UIButtonTypeRoundedRect];        [testButton setFrame:CGRectMake(20, 100, 100, 70)];        [testButton setTitle:@"測試" forState:UIControlStateNormal];    [testButton addTarget:self action:@selector(testPressed:) forControlEvents:UIControlEventTouchUpInside];    [self.view addSubview:testButton];                }-(void) testPressed:(id) sender{        [dm setValue:@"wangzi" forKey:@"name"];        }-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{    if([keyPath isEqualToString:@"name"])    {        testLabel.text = (NSString *)[dm valueForKey:@"name"];    }}- (void)dealloc{            [testLabel release];        [dm removeObserver:self forKeyPath:@"name"];        [dm release];        [super dealloc];    }
上述代碼中,我們設定了label的文字會隨著datamodel類中的一個key的值變化而變化,這就是KVO的一個簡單的運用。但KVO是基於KVC實現的,那什麼又是KVC。

KVC:Key-Value Coding,直譯是:索引值編碼。簡單來講,就是給屬性設定值的;複雜來講,根據網上的說法,KVC運用了一個isa-swizzling技術。isa-swizzling就是類型混合指標機制。KVC主要通過isa-swizzling,來實現其內部尋找定位的。isa指標,如其名稱所指,(就是is a kind of的意思),指向維護分發表的對象的類。該分發表實際上包含了指向實作類別中的方法的指標,和其它資料。

比如說如下的第一行KVC的代碼,其實和第二行的普通代碼是等效的:

[myClass setValue:@"daren" forKey:@"name"];

myClass._name = @"daren";


KVC的代碼會被編譯器處理成:

SEL sel = sel_get_uid ("setValue:forKey:");
IMP method = objc_msg_lookup (myClass->isa,sel);
method(site, sel, @"daren", @"name");


這下KVC內部的實現就很清楚的清楚了:一個對象在調用setValue的時候:

a.  首先根據方法名找到運行方法的時候所需要的環境參數。

b.  它會從自己isa指標結合環境參數,找到具體的方法實現的介面。

c.  再直接尋找得來的具體的方法實現。


和notification的區別也是在,KVO是對象之間直接的互動,而notification需要notificationCenter來做為中間互動。 以上都是一些比較淺的理解,更深層次的原理,還需要大家來補充~~~~

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.