手动设定实例变量的KVO实现监听

简介:

手动设定实例变量的KVO实现监听

如果将一个对象设定成属性,这个属性是自动支持KVO的,如果这个对象是一个实例变量,那么,这个KVO是需要我们自己来实现的.

以下给出源码供君测试:

Student.h 与 Student.m

//
//  Student.h
//  SuperNotification
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Student : NSObject

{
    NSString  *_age;
}
- (void)setAge:(NSString *)age;
- (NSString *)age;

@property (nonatomic, strong) NSString  *name;

@end


//
//  Student.m
//  SuperNotification
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "Student.h"

@implementation Student

@synthesize name = _name;
- (void)setName:(NSString *)name
{
    _name = name;
}
- (NSString *)name
{
    return _name;
}


// 手动设定KVO
- (void)setAge:(NSString *)age
{
    [self willChangeValueForKey:@"age"];
    _age = age;
    [self didChangeValueForKey:@"age"];
}
- (NSString *)age
{
    return _age;
}
+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key
{
    // 如果监测到键值为age,则指定为非自动监听对象
    if ([key isEqualToString:@"age"])
    {
        return NO;
    }
    
    return [super automaticallyNotifiesObserversForKey:key];
}

@end

具体使用情况:
//
//  RootViewController.m
//  SuperNotification
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "RootViewController.h"
#import "Student.h"

@interface RootViewController ()

@property (nonatomic, strong) Student *student;

@end

@implementation RootViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // 创建学生对象
    _student = [Student new];
    
    // 监听属性name
    [_student addObserver:self
               forKeyPath:@"name"  // 属性
                  options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
                  context:nil];
    
    // 监听实例变量age
    [_student addObserver:self
               forKeyPath:@"age"   // 实例变量
                  options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
                  context:nil];
    
    _student.name = @"YouXianMing"; // 改变名字
    _student.age  = @"18";          // 改变年龄
}

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    NSLog(@"%@", change);
}

@end

这个是手动实现KVO需要注意的地方:

目录
相关文章
|
6月前
|
缓存
|
14天前
|
设计模式
在静态方法中访问类的实例属性和方法时会发生什么?
总之,静态方法主要用于处理与类本身相关的操作和逻辑,不应该直接访问类的实例属性和方法。如果需要在静态方法中使用与实例相关的信息,应该通过合理的参数传递或其他设计模式来实现,以保持代码的清晰性和面向对象设计的原则。
42 8
|
6月前
当监听的属性是对象的引用时,`watch`选项是否会触发监听?
当监听的属性是对象的引用时,`watch`选项是否会触发监听?
40 2
Listener概述、监听对象的创建和销毁、监听域对象属性变化、监听会话相关的感知型监听器及监听器实现
Listener概述、监听对象的创建和销毁、监听域对象属性变化、监听会话相关的感知型监听器及监听器实现
104 0
KVO的使用(键值监听)
KVO的使用(键值监听)
62 0
|
Java C#
C#的构造器以及内存状态
C#的构造器以及内存状态
99 0
KVO 解析
KVO解析(一) —— 基本了解KVO解析(二) —— 一个简单的KVO实现KVO解析(三) —— KVO合规性KVO解析(四) —— Faults and KVO Notifications
843 0