属性关键字的作用
来源:互联网 发布:js跨域请求的问题 编辑:程序博客网 时间:2024/05/29 14:00
属性关键字的作用
现在我们iOS开发中,基本都是使用ARC(自动引用计数)技术,来编写我们的代码。因此在属性property中我们经常使用的关键字有strong,weak,assign,copy,nonatomic,atomic,readonly,readwrite,getter,setter。可能经常写代码的朋友,已经很清楚在什么情况下会使用他们。但可能并不清楚他们的含义,下面我先通过一张表总结下他们的作用:
属性关键字的作用
属性关键字
对属性的作用
strong
释放旧对象 将旧对象的值赋予输入对象 ,再提高输入对象的索引计数为1 ,常使用在继承自 NSObject 的类。
weak
weak 不增加对对象的引用计数,也不持有对象,因此不能决定对象的释放。它比 assign 多了一个功能,当对象消失后自动把指针变成 nil
assign
简单赋值 ,不更改索引计数 ,适用于基础数据类型( NSInteger CGFloat )和 C 数据类型( int float double char 等)简单数据类型。
copy
建立一个索引计数为 1 的对象 然后释放旧对象 对 NSString 它指出 ,在赋值时使用传入值的一份拷贝 ,拷贝工作由 copy 方法执行,此属性只对那些实行了 NSCopying 协议的对象类型有效。
atomic
和 nonatomic 用来决定编译器生成的 getter 和 setter 是否为原子操作 ,atomic 设置成员变量的 @property 属性时 默认为是 atomic 提供线程安全。在多线程环境下 ,原子操作是必要的 否则会引起错误的结果 。
nonatomic
非原子性访问 对于属性赋值的时候不加锁 ,多线程并发访问会提高性能,如果不加此属性 则默认是两个访问方法都为原子型事务访问。
readonly
此标记说明属性是只读的
readwrite
此标记说明属性会被当成读写的 这也是默认的属性
unsafe_unretained
跟 weak 类似,声明一个弱引用,但是当引用计数为 0 时,变量不会自动设置为 nil
getter
指定 get 方法,并需要实现这个方法 。必须返回与声明类型相同的变量,没有参数
setter
指定 set 方法,并需要实现这个方法 。带一个与声明类型相同的参数,没有返回值(返回空值)
当声明为 readonly 的时候,不能指定 set 方法
用一个形象的例子说明assign,strong,copy的作用
NSString *houseOfMM = [[NSString alloc] initWithString:'MM的三室两厅'];
上面一段代码会执行以下两个动作:
1 在堆上分配一段内存用来存储@' MM的三室两厅 ' ,比如:内存地址为 0X1111 内容为 ' MM的三室两厅' ,
2 在栈上分配一段内存用来存储 houseForWife ,比如:地址为 0XAAAA 内容自然为 0X1111
然后我们分别看下(assign,strong,copy)使用场景:
1.assign的情况: NSString * myHouse = [ houseOfMM assign ];
此时 myHouse 和 houseOfMM 完全相同,地址都是 0XAAAA ,内容为 0X1111 ,即 myHouse 只是 houseOfMM 的别名,对任何一个操作就等于对另一个操作。因此 retainCount 不需要增加.(同进同出,关系好,一把钥匙,给我拿着)
2.retain的情况: NSString * myHouse = [ houseOfMM retain ];
此时 myHouse 的地址不再为 0XAAAA ,可能为 0XAABB ,但是内容依然为 0X1111 .因此 myHouse 和 houseOfMM都可以管理' 装梵几的三室两厅 '所在的内存。因此 retainCount 需要增加1.(有些独立,各自进出,两把钥匙)
3.copy的情况: NSString * myHouse = [ houseOfMM copy ];
此时会在堆上重新开辟一段内存存放@'MM的三室两厅',比如0X1122,内容为@'MM的三室两厅',同时会在栈上为myHouse分配空间,比如地址:0XAACC,内容为0X1122,因此retainCount增加1供myHouse来管理0X1122这段内存.(两套@'装梵几的三室两厅',条件好,分居了,房子一人一套,所以钥匙一人一把。)
关键字(assign,strong,copy)的使用场景
什么时候用assign,当然是破房子,简装的房子拉
基础类型(简单类型,原子类型):NSInteger,CGPoint,CGFloat,C数据类型(int,float,double,char等)
什么时候用copy
含有可深拷贝的mutable子类的类,如NSArray,NSSet,NSDictionary,NSData的,NSCharacterSet,NSIndexSet,NSString
(可深度拷贝的房子)
但是NSMutableArray这样的不可以,Mutable的不能用copy,不然初始化会有问题。切记
什么时候用strong
NSObject和其子类对象
weak:由ARC引入的对象变量的属性,比assign多了一个功能,对象消失后把指针置为nil,避免了野指针(不是null指针,是指向“垃圾”内存(不可用的内存)的指针)
用下面这张表来总结下关键字(assign,strong,copy)的使用场景
关键字 (assign,strong,copy) 的使用场景
assign
基本数据类型 , 如: NSInteger,CGPoint,CGFloat,C 数据类型( int,float,double,char 等)
copy
含有可深拷贝的 mutable 子类的类,如 NSArray , NSSet , NSDictionary , NSData 的, NSCharacterSet , NSIndexSet , NSString
strong/weak
NSObject 和其子类对象好嘛 (Cocoa 框架的类以及我们多数自定义的类)
属性关键字的对比
1.copy与strong
1.copy 其实是建立了一个相同的对象 ,而strong不是 比如说 个NSString对象 地址是0x1111 内容为@"STR" ,copy到另外一个NSString之后 ,地址为0x2222 内容相同 新的对象retain 为 1 ,旧有对象没 有变化 ; retain到另外一个NSString之后,地址相同(建立了一个指针,指针拷贝)内容当然相同 这个对象的retain值+1 也就是说 retain 是指针拷贝 copy 是内容拷贝。
2.strong的set方法是浅拷贝 copy的set方法是深拷贝
3.copy的另外一个用法:
copy是内容拷贝 对于像NSString的确是这样的 但是如果copy的对象是NSArray
比如:NSArray*array = [NSArray arrayWithObjects:@"hello",@"world",@"baby"];
NSArray*array2 = [array copy];
这个时候 系统的确是为array2 开辟了一块新的内存空间 但是 array2中的每个元素 只是copy了指向array中相对应元素的指针 这便是所谓的浅复制。
2.assign和strong
1.类似与C语言 当你malloc分配了一块内存 并且把它的地址赋给了指针a ,后来希望指针b也共享这一块内存 ,于是你又把a赋值给(assign)了b 。此时a和 b 指向同一块空间 ,当a不再需要这块内存的时候 ,能否直接释放它 答案是否定的 ,因为a并不知道b是否还在使用这块内存 ,如果a释放掉了这块内存 那么b在使用这块内存的时候 程序会crash掉
2.1当中assign出现的问题如何解决 最简单的方法就是使用引用计数 (reference counting),还是上面的哪个例子 我们给内存设一个引用计数 当内存被分配并赋值给a 的时候 引用计数是1, 当把a赋值给b的时候 引用计数为2 这时如果a不再使用这块内存 ,它只需要把引用计数减1 表明自己不再用于这块内存 。b不再使用这块内存的时候也把引用计数减1 当引用计数为0 的时候 ,代表该内存不再被任何指针指向 系统可以直接把它释放掉。
总结:上面两点就是assign和strong的区别 assign就是直接赋值 从而可能引起1.中的问题 当数据为int float等原生类型的时候,可以使用assign strong就如2.中所描述的问题一样 使用了引用计数 retain引起引用计数加1 release 引起引用计数减1 当引用计数为0的时候 dealloc函数被调用 内存被回收。
- 属性关键字的作用
- @property属性关键字的作用
- 关键字static的作用
- volatile关键字的作用
- sealed关键字的作用
- transient关键字的作用
- transient关键字的作用
- partial关键字的作用
- 关键字static的作用
- 关键字explicit的作用
- 关键字的作用
- static关键字的作用
- __noop关键字的作用
- static关键字的作用
- finale 关键字的作用
- static关键字的作用
- explicit关键字的作用
- volatile关键字的作用
- Python urllib2.HTTPError: HTTP Error 304: Not Modified
- Android Design Support Library 使用
- text——修改android系统默认字体大小
- 2016年8月25号
- mysql 带参数的存储过程
- 属性关键字的作用
- 泛型中? super T和? extends T的区别
- 在构建新项目时可能会出现的问题
- QVariant自定义类型例子及机制分析
- BIOS基本输入输出系统
- 五十道编程小题目 --- 11 排列与组合(阶乘) java
- 为什么NSString要用Copy来修饰?
- ScrollView和Listview嵌套冲突问题解决
- 欢迎使用CSDN-markdown编辑器