您的位置:首页 > 大数据 > 人工智能

OC @property 指示符assign、atomic、copy、retain、strong、week、等

2016-10-24 10:49 393 查看
在使用@property定义property时可以在@property与类型之间用括号添加一些额外的指示符,常用的指示符有assign、atomic、copy、retain、strong、week、等。下面对它们的用途和常常对应的属性讲解一下。
assign:该指示符号对属性只是简单的赋值,不更改引用计数。常用于NSInteger等OC基础类型,以及short、int、double、结构体等C数据类型,因为这些类型不存在被内存回收的问题。

atomic、nonatomic:指定setter和getter是否是原子操作,即是否线程安全。如果是atomic,那么存取方法都是线程安全的,即某一线程访问存或者取方法,其他线程不可以进入该存、取方法。nonatomic则不具备线程安全的功能。需要指出的是atomic是默认值,可以保证数据的完整性,但是相应的降低了性能,所以在单线程环境中建议使用nonatomic来提升性能。

copy:如果使用copy指示符,当调用setter方法对成员变量赋值时,会将被赋值的对象复制的一个副本,再将该副本给成员变量,相应的原先的被赋值的对象的引用计数加1。当成员变量的类型是可变类型,或其子类是可变类型,被赋值的对象在赋值后有可能再被修改,如果不需要这种修改,则可以考虑copy指示符。

getter、setter:用于为getter方法、setter方法指定自定义方法名。比如getter=myName,setter=setName:,我们可以看到setter方法后面有一个(:),这是因为我们需要在后面添加参数。

readonly、readwrite:readonly指示系统只合成getter方法,不合成setter方法;readwrite是默认值,指示系统需要合成setter方法和getter方法。

retain:当把某个对象赋值给该属性时,该属性原来所引用的对象的引用计数减1,被赋值对象的引用计数加1。在未启用ARC机制的的情况下,retain可以保证一个对象的引用计数大于1时,该对象不会被回收。启用ARC后一般较少使用retain

strong、weak:strong指示符该属性对被赋值对象持有强引用,而weak指示符指定该属性对被赋值对象持有弱引用。强引用的意思是:只要该强引用指向被赋值的对象,那么该对象就不会自动回收。弱引用的意思是:即使该弱引用指向被赋值的对象,该对象也可能被回收。如果不希望对象被回收,可以使用strong指示符。如果需要保证程序性能,避免内存溢出,可以使用weak,内存一旦被回收,指针会被赋值为nil。

unsafe_unretained:与weak不同,被unsafe_unretained指针所引用的对象被回收后,unsafe_unretained指针不会被赋为nil,可能会导致程序出错。

1、atomic是默认行为,assign是默认行为,readwrite是默认行为

2、推荐做法是NSString用copy
3、delegate用assign(且一定要用assign)
4、非objc数据类型,比如int,float等基本数据类型用assign(默认就是assign)
5、其它objc类型,比如NSArray,NSDate用retain。

OC中提供了4个访问控制符:@private @package @protected @public。
@private(当前类访问权限):成员只能在当前类内部可以访问,在类实现部分定义的成员变量相当于默认使用了这种访问权限。
@package(同映像访问权限):成员可以在当前类或和当前类实现的同一映像中使用。同一映像就是编译后生成的同一框架或同一个执行文件。
@protected(子类访问权限):成员可以在当前类和当前类的子类中访问。在类接口部分定义的成员变量默认是这种访问权限。
@public(公共访问权限):成员可以在任意地方访问。
@private
@package
@protected
@public
同一个类中
同一个映像中
子类中
全局范围
下面使用@private来实现Person类,用来封装Person的2个属性,并将方法暴露出来:
[objc] view plain copy







#import <Foundation/Foundation.h>

@interface Person : NSObject{

//使用@private限制成员变量

@private

NSString* _name;

int _age;

}

//声明_name的set方法

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

//声明_name的get方法

-(NSString*)name;

//声明_age的set方法

-(void)setAge:(int)age;

//声明_age的get方法

-(int)age;

@end

#import "Person.h"

@implementation Person

//声明_name的set方法

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

_name = name;

}

//声明_name的get方法

-(NSString*)name{

return _name;

}

//声明_age的set方法

-(void)setAge:(int)age{

_age = age;

}

//声明_age的get方法

-(int)age{

return _age;

}

@end

#import <Foundation/Foundation.h>

#import "Person.h"

int main(int argc, const charchar * argv[]) {

@autoreleasepool {

Person* person = [[Person alloc]init];

//报错,age已经被封装起来,对外不可见

//person->_age = 10;

[person setAge:10];

NSLog(@"age:%d",[person age]);

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  OC @property 指示符assi
相关文章推荐