Cocoa 数据绑定 bind 教程

本文详细介绍了Cocoa数据绑定机制,包括KVC、KVO和KVB,以及如何使用它们简化MVC模式下的数据更新流程。通过数据绑定,可以减少模型和视图之间的繁琐代码,实现模型和视图的双向数据同步。文中还通过实例演示了如何使用NSArrayController和NSTreeController管理数据。
摘要由CSDN通过智能技术生成

Cocoa数据绑定

MVC架构编程模式中,Controller负责将Model模型数据更新到View视图,同时当用户对视图View数据做了修改后,还需要Controller将变换的数据更新到Model模型中。

MVCMode

模型Model到视图View,视图View到模型Model,这种双向的数据更新涉及到大量繁琐的数据转换和赋值操作。因此OSX Cocoa从系统层面设计了Cocoa数据绑定机制,用以简化MVC编程中这种双向更新操作。

Cocoa数据绑定机制的实现依赖KVC,KVO,KVB 三种技术,下面分别来介绍说明。

KVC

KVC是Key-value coding 键值编码的简称,提供了通过类的属性字符名称来读写属性值的方法。你不需要通过调用类的不同的方法去实现不同的属性读写修改,而只需要通过不同的属性名称,通过统一一致的接口实现读写。

KVC的好处是明显的,可以实现循环遍历读写所有的属性值,也可以支持属性路径链式调用,即嵌套对象的访问。

Cocoa在基类NSObject上实现了KVC的接口方法,因此所有类天然支持KVC方式属性读写。

我们定义Person和Phone 2个类便于后面说明KVC的属性访问方式。

Person对象类,有3个属性:名字,年龄,电话。

@interface Person : NSObject
@property(nonatomic,strong)NSString *name;
@property(nonatomic,assign)int age;
@property(nonatomic,strong)Phone  *phone;
@end

电话对象类,有3个属性:办公电话,家庭电话,手机。

@interface Phone : NSObject
@property(nonatomic,strong)NSString *office;
@property(nonatomic,strong)NSString *family;
@property(nonatomic,strong)NSString *mobile;
@end

定义Person和Phone实例

Person *person= [[Person alloc]init];
person.name = @"john";
person.age = 20;

Phone *phone = [[Phone alloc]init];
phone.office = @"010-67854545";

person.phone = phone;

属性读写接口

1.通过名字访问对象属性值

-(id)valueForKey:(NSString *)key;

2.修改属性名为key的值为value

-(void)setValue:(id)value forKey:(NSString *)key;

//使用KVC方法获取属性    
NSString *name = [person valueForKey:@"name"];
//使用KVC修改属性
[person setValue:@"Habo" forKey:@"name"];

路径访问接口

1.使用keyPath路径去获取属性

-(id)valueForKeyPath:(NSString *)keyPath;

2.更新keyPath路径对应的属性值为value

-(void)setValue:(id)value forKeyPath:(NSString *)keyPath;

//使用path获取属性
NSString *officePhone = [person valueForKeyPath:@"phone.office"];
//修改属性
[person setValue:@"010-678545466" forKeyPath:@"phone.office"];

异常属性接口

1.访问不存在的属性,会调用此方法,如果此方法没有实现,会抛出异常。

-(id)valueForUndefinedKey:(NSString *)key;

2.修改不存在的属性值,会调用此方法,如果此方法没有实现,会抛出异常。

-(void)setValue:(id)value forUndefinedKey:(NSString *)key;

3.修改属性值为nil,会调用此方法,如果此方法没有实现,会抛出异常

-(void)setNilValueForKey:(NSString *)key;

下面是用使用setValue方法对hidden属性修改为nil,默认设置为YES

- (void)setNilValueForKey:(NSString *)theKey {
    if ([theKey isEqualToString:@"hidden"]) {
        [self setValue:@YES forKey:@"hidden"];
} else { 
        [super setNilValueForKey:theKey];
    }
} 

4.修改key对应的value值,对value进行有效性验证。

对每个Key单独实现validate方法
-(BOOL)validate:(id *)ioValue error:(NSError * *)outError;

下面是对Person对象的age年龄进行validate的例子:

- (BOOL)validateAge:(id *)ioValue error:(NSError * __autoreleasing *)outError 
    if ([*ioValue integerValue] <= 0) {
        if (outError != NULL) {
            NSString *errorString = NSLocalizedStringFromTable(@"Age must be greater than zero", @"Person",
                                                               @"validation: zero age error");
            NSDictionary *userInfoDict = @{ NSLocalizedDescriptionKey : errorString };
            
            NSError *error = [[NSError alloc] initWithDomain:@""     code:10005   userInfo:userInfoDict];
                                            *outError = error;
        };
        return NO;
    }
    return YES;
}

对所有Key统一实现validate方法

-(BOOL)validateValue:(inout id )ioValue forKey:(NSString *)inKey error:(NSError **)outError;
-(BOOL)validateValue:(inout id )ioValue forKeyPath:(NSString *)inKeyPath error:(out NSError **)outError;

在-set:方法中不要执行validation方法,如果需要对key的值修改进行有效性验证,在类中实现validation方法。

批量属性访问接口

1.访问多个key对应的属性,返回key-value形式的字典对象

-(NSDictionary *)dictionaryWithValuesForKeys:(NSArray *)keys;

2.以字典对应的key-value去更新对象对应的属性。

-(void)setValuesForKeysWithDictionary:(NSDictionary *)keyedValues;

使用这个方法在网络处理JSON对象解析中可以方便通过字典对象来更新模型对象。

@interface Phone : NSObject
@property(nonatomic,strong)NSString *office;
@property(nonatomic,strong)NSString *family;
@property(nonatomic,strong)NSString *mobile;
-(id)initWithDictionary:(NSDictionary*)attributes;
@end

#import "Phone.h"

@implementation Phone
-(id)initWithDictionary:(NSDictionary*)attributes {
    self = [super
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值