Home 响应式编程
Post
Cancel

响应式编程

响应式编程

假设有一个父类Person,它有个属性age,我们创建一个它的子类 LYKVONotifying_Person。

我们给所有类一个扩展方法:

1
- (void)ly_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;

实现这个方法:

实质是修改这个对象的isa指针,把当前对象指向一个新的类,然后给对象绑定观察者对象。

1
2
3
4
5
6
7
- (void)ly_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context{
    //修改isa指针,就是把当前对象指向一个新的类
    object_setClass(self, [LYKVONotifying_Person class]);
    
    //给对象绑定观察者对象
    objc_setAssociatedObject(self, @"observer", observer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

最后重写这个子类的 setAge 方法:

每次调用setAge方法,都会调用观察者的observeValueForKeyPath方法

1
2
3
4
5
6
7
8
9
10
- (void)setAge:(int)age{
    
    [super setAge:age];
    //KVO
    //获取观察者
    id observer = objc_getAssociatedObject(self, @"observer");
    
    //调用观察者方法
    [observer observeValueForKeyPath:@"age" ofObject:observer change:nil context:nil];
}

检验:

1
2
3
4
5
6
7
8
9
10
11
12
- (void)viewDidLoad {
    [super viewDidLoad];
    
    //创建一个父类的对象
    Person *p = [[Person alloc] init];
    p.age = 0;
    _person = p;
    
    //调用新的注册观察者方法
    [p ly_addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew context:nil];

}

响应:

1
2
3
4
5
6
//响应方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
    
    NSLog(@"Person Age %d Changed",_person.age);
}

点击按钮,设置person的age属性:

1
2
3
4
5
6
7
8
- (IBAction)changeAge:(id)sender {
    //0~99随机数
    int newAge = arc4random_uniform(100);
    NSLog(@"New Age -> %d",newAge);
    //调用setAge方法
    _person.age = newAge;
}

打印结果:


可见:一旦吊用了setAge方法,就会响应。

This post is licensed under CC BY 4.0 by the author.

合并UIImage

工厂模式