属性是什么
通常意义我们使用类的属性无非两种(getter和setter),访问属性和设置属性这两种。Objective-C(一下简称OC)中的属性也离不开这两点,OC中为属性的访问控制方法(getter和setter)遵循封装的原则,我们不需要知道底层的具体实现,我们只需要按照约定定义使用即可。
OC中的属性
OC中的属性定义和方法封装时考虑的因素也是非常多,一下我简单列举了一些:
- OC中属性要支持引用计数,也就是内存管理等。
- 属性定义要对线程处理,考虑线程安全。
- 还需要考虑属性的作用域,private和public等。
属性的声明
@property 在类的接口定义@interface中的方法列表中定义。
#import <Foundation/Foundation.h>
@interface Person:NSObiect
@property NSString *name;
@end
其作用有:
- 自动生成访问方法,同时生成get和set方法;
-(void)setName:(NSString*)name;
-(NSString*)name;
- 自动生成实例变量,编程时直接使用;
- 更简单调用访问方法可以使用点语法;
Persion *teacher = [[Persion alloc]init];
teacher.name = @"gavin";
原子性 我们通常定义属性的时候标注属性的原子性和非原子性.
@property(nonatomic,copy) NSString *name;
那么到底什么是原子性呢?其实原子性主要是在多线程的环境中的安全,也就是在get和set不会因为线程的并发造成影响,但是相对非原子会消耗部分性能。示例中nonatomic 是访问非原子,不加则是原子性。如下可以看出原子性的实现:
-(Type)name{
[_internal lock];//加锁
Type returnType = [[_name retain]autorelease];
[_internal unlock];
return returnType;
}
-(void)setName:(Type)obj{
[_internal lock];
if (name != obj){
[name release];
name = [obj retain];
}
[_internal unlock];
}
如果我们使用了retain或者copy而没有使用nonatomic,那么在引用计数环境中,自动生成的getter方法中会先上锁,然后在持有原来的对象,再向对象发送autorelease方法,最后解锁并返回其值。
有时候我们定义属性不希望系统(编译器)帮我们实现getter和setter方法,那么这个时候我们怎么做呢?
@synthesize 该指令告诉编译器如果在@impementation中没有实现属性的getter和setter就自动生成之。
@interface Person:NSobject{
@property(nonatomic,strong) NSString *name;
}
@impementation Person
@synthesize name;
@end
@dynamic指令告诉编译器我们自己实现setter和getter方法,或者在运行时我们动态的添加方法,实现我们的功能
实现属性的指令
@interface Person:NSObject{
@property(nonatomic,strong) NSString *name;
}
@impementation Person
@dynamic name;
@end
从上面代码中可以看到我们在定义属性的时候使用了“strong”,那这又有什么用呢?
其中属性的读写特性有哪些?
类属性的copy又将如何实现,类继承之后属性又将如何变化?