oc学习之旅:KVO

来源:互联网 发布:查看linux网络地址 编辑:程序博客网 时间:2024/06/06 11:49

#import <Foundation/Foundation.h>

#import "Bank.h"

#import "Person.h"

int main(int argc,const char * argv[])

{


    @autoreleasepool {

        

       /*

         KVC:义字符串替代访问器(getter setter)修改成员变量

         KVO:Key Value Observer 键值观察者

         适用范围:监听对象的某一个属性是否发生变化

         

         有观察者对象A 被观察对象B

         1.A作为B对象的观察者         [A addObserver:A forKeyPath:B的属性(count) options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:NULL];

         2.当程序的任意位置修改了B对形象的这个属性(count)

         3.系统会自动触发A对象中的 observeValueForKeyPath方法

         4.dealloc 中移除观察者身份 removeObserver

         

         */

       Bank *bank = [[[Bankalloc] init]autorelease];

       while (1) {

             [[NSRunLoopcurrentRunLoop] runUntilDate:[NSDatedateWithTimeIntervalSinceNow:1]];

//            [bank setValue:[NSNumber numberWithInt:10.0] forKeyPath:@"_userA.count"];

//            [bank myChange];

           Person * p = bank.accountArr[4];

            [bank.accountArr[4]myChange];

        }

               

    }

   return 0;

}


Bank.h

#import <Foundation/Foundation.h>

#import "Person.h"

@interface Bank : NSObject

{

   Person *_userA;

   NSMutableArray *_accountArr;

}

@property (nonatomic,assign)Person *userA;

@property (nonatomic,retain)NSMutableArray *accountArr;

@end


Bank.m

#import "Bank.h"


@implementation Bank


@synthesize userA = _userA;

@synthesize accountArr =_accountArr;

- (void)dealloc

{

    //2.移除掉观察者身份 ARCARC都要写

    [selfremoveAll];

    [_accountArr release];

    [_userAremoveObserver:selfforKeyPath:@"count"];

    [_userArelease];

    [superdealloc];

}


- (id)init

{

   self = [superinit];

   if (self) {

       _userA = [[Personalloc] init];

       //KVO写法

        /*1.添加观察者

         参数一:观察者对象

         参数二:观察着对象的某一个属性

         参数三:改变前后的值

        */

        [_userAaddObserver:selfforKeyPath:@"count"options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOldcontext:NULL];

        

       _accountArr = [[NSMutableArrayalloc] init];

        

       for (int i =0; i <10; i++) {

           Person *p = [[Personalloc] init];

            

            

            p.name = [NSStringstringWithFormat:@"zhangsan%2d",i];

            [_accountArraddObject:p];

            [p addObserver:selfforKeyPath:@"count"options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOldcontext:NULL];


            

            

            [prelease];

        }

        

    }

    return self;

}

-(void)removeAll

{

   for(Person *pin _accountArr)

    {

        [p removeObserver:selfforKeyPath:@"count" ];

        [prelease];

    }

}

//系统自动调用 不许手动调用 当监听的属性发生变化时自动调用

//1.监听的属性(Person class 2.监听的对象 3.属性变化的新旧值 4.NULL

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

{

   if ([keyPath isEqualToString:@"count"]) {

       Person *p =  (Person *)object;

       NSLog(@"%@ %@",p.name,[changeobjectForKey:@"new"]);

    }

//    NSLog(@"%@,%@,%@",object,keyPath,change);

}


@end


Person.h

{

   float _count;

   NSString *_name;

}

@property (nonatomic,assign)float count;

@property (nonatomic,assign)NSString * name;

-(void)myChange;


Person.m

@synthesize count = _count;

@synthesize name = _name;


-(void)dealloc

{

   self.name =nil;

    [superdealloc];

}


- (id)init

{

   self = [superinit];

   if (self) {

       _count = 100;

    }

    return self;

}

-(void)myChange

{

   if (_count>10) {

        //_count -=10;

        //直接访问成员变量不能触发KVO _count = 100;不能触发KVO

        //需要间接访问成员变量

/*       1.

        float t =self.count;

        t -= 10;

        self.count =t;

 */

/*        2.点语法可以出发KVO

 */

       self.count -=10;

/*      3.

        [self willChangeValueForKey:@"count"];

        _count -= 10;

        [self didChangeValueForKey:@"count"];

 */

    }

}



0 0
原创粉丝点击