OC学习第八天_属性 属性的Attribute 点语法 KVC

⼀、属性
属性
属性是Objective-C 2.0定义的语法,为实例变量提供了setter、
getter⽅法的默认实现
能在⼀定程度上简化程序代码,并且增强实例变量的访问安全性。
属性的定义
属性的声明:使⽤@property声明属性
例如:@property NSString *name;
相当于@interface中声明了两个⽅法(setter、getter):
- (void)setName:(NSString *)name;
- (NSString *)name;
属性的实现
属性的实现:使⽤@synthesize实现属性
例如:@synthesize name = _name;
相当于@implementation实现了setter、getter
- (void)setName:(NSString *)name
{…}
- (NSString *)name
{…}
练习1
定义⼀个完整的Teacher类,包含实例变量、属性、初始化⽅法、便
利构造器⽅法,以及功能⽅法。

//  Teacher.h代码
#import<Foundation/Foundation.h>

@interface Teacher : NSObject
{
    NSString *_name;
    NSString *_gender;
    NSString *_subject;
}
@property NSString *name;
@property NSString *gender;
@property NSString *subject;

- (instancetype)initWithName:(NSString *)name
                      gender:(NSString *)gender
                     subject:(NSString *)subject;
+ (instancetype)teacherWithName:(NSString *)name
                      gender:(NSString *)gender
                     subject:(NSString *)subject;
- (void)teaching;

@end

//  Teacher.m代码
#import "Teacher.h"

@implementation Teacher
//  实现set get方法
//  指定要赋值的成员变量

@synthesize name = _name;
@synthesize gender = _gender;
@synthesize subject = _subject;

-(instancetype)initWithName:(NSString *)name gender:(NSString *)gender subject:(NSString *)subject
{
    self = [super init];
    if (self) {
        _name = name;
        _gender = gender;
        _subject = subject;
    }
    return self;

}

+ (instancetype)teacherWithName:(NSString *)name gender:(NSString *)gender subject:(NSString *)subject
{
    Teacher *teacher = [[Teacher alloc]initWithName:name gender:gender subject:subject];
    return teacher;
}

- (void)teaching
{
    NSLog(@"授课");
}
@end

⼆、属性的属性
属性的属性
Objective-C提供属性的⺫的是为了简化程序员编码
为属性提供了⼀些关键字⽤以控制setter、getter的实现细节
这些关键字我们称为属性的属性(attribute)
⼀共3⼤类attribute。

第⼀类:读写性控制(readonly、readwrite、setter、getter)
readonly,告诉编译器,只声明getter⽅法(⽆setter⽅法)。
例如:@property(readonly)NSString *name;
//等价于 - (NSString *)name;0
readwrite,告诉编译器,既声明setter⼜声明getter。
例如: @property(readwrite)NSString *name;
//等价于 - (NSString *)name;
- (void)setName:(NSString *)name;
readwrite是读写性控制的默认设置。

//  1.读写类属性
//  readonly 只读 (系统就不会默认生成set方法)
//  readwrite 读写 (如果你什么都不写 默认的就是可读写)
//  setter  设置指定set方法,默认生成方法名
//  getter  设置指定get方法,默认生成方法名
@property (readwrite, setter=aa:,getter=bb) NSString *name;

第⼆类:原⼦性控制(nonatomic、atomic)
atomic。setter、getter⽅法在多线程访问下是绝对安全的,即
setter、getter内部做了多线程访问处理。原⼦性控制的默认设置是
atomic
nonatomic。setter、getter⽅法内部不会做多线程访问处理,仅仅是
普通的setter、getter⽅法
属性的属性
程序开发过程中,setter、getter处处都在⽤,如果使⽤atomic,需要不断
的对setter、getter加锁解锁以保证线程访问安全,会很占⽤系统资源,降低
系统性能。
通常设置为nonatomic,某些属性需要线程安全的时候,才定义为atomic。
例如:@property (readwrite,nonatomic)NSString *name;
//等价于
- (NSString *)name;
- (void)setName:(NSString *)name;

// nonatomic 没有实现多线程访问一个变量上的操作保护
// atomic (如果什么都不写 默认的)添加对多线程的保护操作 虽然安全 但是大量耗费系统资源 并且这个资源 是不必要浪费的 所以一般使用 nonatomic

第三类:语义设置(assign、retain、copy)
assign。setter、getter内部实现是直接赋值。
例如:@property(nonatomic,assign)NSString *name;
- (void)setName:(NSString *)name{
_name = name;
}
- (NSString *)name{
return _name;
}

retain。setter、getter的内部实现会做内存优化。
例如:@property(nonatomic,retain)NSString *name;
- (void)setName:(NSString *)name{
if(_name != name){
[_name release];
_name = [name retain];
}
}
- (NSString *)name{
return [[_name retain]autorelease];
}

copy。setter、getter的内部实现也会做内存优化。
例如:@property(nonatomic,copy)NSString *name;
- (void)setName:(NSString *)name{
if(_name != name){
[_name release];
_name = [name copy];
}
}
- (NSString *)name{
return [[_name retain]autorelease];
}

如果属性是⾮对象类型(⽐如int,float等)属性的语义设置使⽤
assign。
如果属性是对象类型(⽐如NSStrng、NSArray等)属性的语义设
置使⽤retain。
如果属性是对象类型并且想得到参数的copy,使⽤copy关键字。
练习2
定义⼀个完整的Student类,包含属性、初始化⽅法、便利构造器⽅
法,以及功能⽅法。
三、点语法
什么是点语法
点语法是Objective-C 2.0中定义的语法格式。提供了⼀种便捷的
属性访问⽅式。
点语法的使⽤
凡是符合系统默认setter、getter书写格式的⽅法都可以使⽤点语
法。
例如:[person1 setName:@”zhangsan”];可以等价写成
person1.name = @”zhangsan”;。
NSString *name = [person1 name];可以等价写成
NSString *name = person1.name;
属性是⼀对getter、setter⽅法,点语法是属性的另⼀种调⽤格式。
练习3
使⽤点语法对Teacher类和Student类进⾏赋值取值。
四、KVC
KVC
KVC(Key-Value-Coding),键值编码,是⼀种间接访问实例变量的⽅
法。
key:键,⽤于标识实例变量
vlaue:实例变量对应的值
修改值
setValue:forKey:
setValue:forKeyPath:
setValue:forUndefinedKey:
setValuesForKeysWithDictionary:
获取值
valueForKey:
valueForKeyPath:
valueForUndefinedKey:
注意事项
当key不存在的时候,会执⾏setValue:forUndefinedKey:
系统默认实现是抛出⼀个异常
课程总结
属性是Objective-C的重要语法,属性是⼀组getter、setter⽅法,内
部对实例变量进⾏操作。
点语法是⼀种属性的另外⼀种调⽤格式。
KVC是⼀种间接访问实例变量的⽅法。

//  如果间接访问的对象时nil时:
- (void)setNilValueForKey:(NSString *)key
{
    //  捕获到value是空的 对应的key

    NSLog(@"%@",key);
}

//  如果你输入的key没有找到时,执行下述方法
//  传入的key的查找顺序
//  _key _iskey key iskey
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
    //  如果你使用间接访问的方法 访问属性的话
    //  需要重写这个方法 防止在系统抛出异常的时候调用这个方法 你没有而产生的崩溃
    //  间接赋值的保护方法
    //  捕获间接访问 属性填错的key和value
    //  如果使用间接访问 那么 必须实现这个方法
    NSLog(@"%@ %@",value,key);

    //  类的复合
    //  本类中包含 其他类的一个对象 作为实例变量

    //  这个方法相当于 跨一级去间接访问属性 是访问本类中属性的属性 通过这个方法去访问的话 需要传入一个路径
    //  填这个路径 一级一级的进行查找
    //  [stu setValue:<#(id)#> forKeyPath:<#(NSString *)#>];
     //  stu是新建的学生的一个对象,里面的set get 都用属性写好了   
    //  通过一个不可变字典去间接赋值一个对象
//    NSDictionary *dic = @{@"name":@"zhangsan",
//                          @"gender":@"nan",
//                          @"age":@"17"
//                          };
//    [stu setValuesForKeysWithDictionary:dic];
//    NSLog(@"姓名:%@ 性别:%@ 年龄:%ld",stu.name,stu.gender,stu.age);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值