8、属性

属性

为实例变量提供了setter、getter⽅法的默认实现
能在⼀定程度上简化程序代码,并且增强实例变量的访问安全性

声明:@property

@property是编译器指令,自动声明set/get方法

@property NSString *name;//写在.h文件中

相当于@interface中声明了两个⽅法(setter、getter):

- (void)setName:(NSString *)name;
- (NSString *)name;

注意:

  • @property只能写在@interface @end中
  • (xcode4.4之前)@property用来自动生成成员变量的set/get方法声明
  • 告诉property要生成的get/set方法声明的成员变量类型是什么
  • 告诉property要生成的set/get方法是什么属性的,属性名称去掉下划线

实现:@synthesize

@synthesize name ;//写在.m文件中

相当于@implementation实现了setter、getter

- (void)setName:(NSString *)name
{
    self->name = name;//此时变量名为name,而不是我们常用的_name
} 
 - (NSString *)name
{
    return name;//此时变量名为name,而不是我们常用的_name
}

注意:方法名(name)一定要现在.h中使用@property NSString * name 进行声明

@synthesize指定实例变量赋值
@synthesize name = _name;//表示用a的get和set方法,修改属性b的值

相当于

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

属性的属性(Attribute)

@property的增强使用

  • xcode4.4之后可以只使用@property而不使用@synthesize
  • 声明和实现了_age,_name

读写性控制

readonly

只声明getter⽅法(⽆setter⽅法)

@property(readonly)NSString *name;//等价于 - (NSString *)name;
readwrite(默认)

既声明setter⼜声明getter。

 @property(readwrite)NSString *name;
//等价于
- (NSString *)name; 
- (void)setName:(NSString *)name; 

原⼦性控制

程序开发过程中,setter、getter处处都在⽤,如果使⽤atomic,需要不断的对setter、getter加锁解锁以保证线程访问安全,会很占⽤系统资源,降低
系统性能。
通常设置为nonatomic,某些属性需要线程安全的时候,才定义为atomic。

@property (readwrite,nonatomic)NSString *name;
//等价于
- (NSString *)name; 
- (void)setName:(NSString *)name;
atomic(默认)

setter、getter⽅法在多线程访问下是绝对安全的,即setter、getter内部做了多线程访问处理

nonatomic

setter、getter⽅法内部不会做多线程访问处理,仅仅是普通的setter、getter⽅法

语义设置

  • 如果属性是⾮对象类型(⽐如int,float等)属性的语义设置使⽤assign
  • 如果属性是对象类型(⽐如NSStrng、NSArray等)属性的语义设置使⽤retain
  • 如果属性是对象类型并且想得到参数的copy,使⽤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];
}

点语法

⼀种便捷的属性访问⽅式,是编译器的特性,即编译器(XCode)帮我们做代码替换
凡是符合系统默认setter、getter书写格式的⽅法都可以使⽤点语法。

[person1 setName:@”zhangsan”];//等价于person1.name = @”zhangsan”; 
NSString *name = [person1 name];//可以等价写成NSString *name = person1.name;

点语法:对象.属性名并不是直接访问实例变量,而是xcode看到点语法后会替换成set或get方法,

在等号左侧(设置值)为set方法,在等号右侧(获取值)为get方法

点语法注意事项

  • set方法里不能用点语法,他会造成死循环

    -(void)setAge:(int)age{
    self.age = age;//self.age会递归调用set方法,造成死循环
    }

  • get方法里不能return点语法,因为return self.age会造成死循环

  • 如果程序中不存在get+set方法,点语法是不可用的


KVC

KVC(Key-Value-Coding),键值编码,是⼀种间接访问实例变量的⽅法。
key:键,⽤于标识实例变量
vlaue:实例变量对应的值
//注意:当key不存在的时候,会执⾏setValue:forUndefinedKey:
系统默认实现是抛出⼀个异常

修改值

setValue:forKey:
setValue:forKeyPath:
setValue:forUndefinedKey:
setValuesForKeysWithDictionary:

获取值

valueForKey:
valueForKeyPath:
valueForUndefinedKey:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值