iOS开发-assign、retain、copy、strong、weak的区别
2015-08-16 00:28
686 查看
对于初学的开发者,对于assign、retain、copy、strong、weak的用法及意义可能不是很明白,我对于这个问题也研究了很久,写篇博文,巧巧代码,让我们来瞧瞧吧!
先定义一个Student类:
接下来初始化一个Student对象,并且敲入以下代码
(一)所以我总结,assign只是使指向stu的栈内存上的的指针,也就是stu换了一个名字,换成了stu1,就是stu和stu1的作用和意义是一样的,谁做了任何改变对应的指向栈内存的内容也会随之改变,但是栈内存的引用计数还是1没有增加。
接下来我们看看retain,改变stu1属性为以下
然后重新运行程序控制台输出为:
(二)再来总结一下,retain是使指向栈内存的指针多了一个,也就是引用计数加1,并且指针stu和stu1对于栈内存的作用是一样的,也就是一扇门多了一把钥匙
接下来再看看copy的作用,同样改变stu属性为copy,但是如果是我们定义的对象,那么我们自己要实现NSCopying,这样就能调用copy,贴出代码
Student.h
viewDidLoad里的代码不变,运行程序,控制台输出
(三)可以看出,stu.name没有改变,而且stu的引用计数没用增加,为什么呢?因为copy是完全复制一段栈内存,所以copy出来的对象与原来的对象是两个不同地址的对象,所以对于stu没有影响
好了,接下来我们看看arc模式下,strong和weak的区别及用法.
先是strong,声明属性
viewDidLoad中的代码
(四)可以看出,当将stu赋值给stu1之后,这两个指针指向的栈内存是一样的,也就是说这里和retain是一样的,但是当我们将stu滞空后,stu1指向的栈内存并没有变为空,这就是strong与retain的区别,当栈内存只要有两个或者两个以上指针指向的时候,对其中指针进行滞空操作都不会释放掉栈内存,也就是strong出来的对象,对于栈内存有控制权,还有一点,arc下默认的赋值方式就是strong
接下来,我们看看weak
其他都一样,把stu1属性改为weak,运行程序,控制台输出
(五)可以看出,当将stu赋值给stu1之后,这两个指针指向的栈内存是一样的,也就是说这里和retain是一样的,但是当我们将stu滞空后,stu1指向的栈内存变为空,这就是weak与strong的区别,也就是weak出来的对象,对于栈内存没有控制权
这里说一下,为什么不用NString测试,因为NString *str = @“dddd”,然后str = @“bbbb”,是新开辟一个栈内存来存放“bbbb”不是在原有的基础上改的。
用string做retain测试,大家会发现,无论怎么样retain,但是改变其中一个变量后,另一个不变。
先定义一个Student类:
#import <Foundation/Foundation.h> @interface Student : NSObject @property (nonatomic, copy) NSString *name; @end然后先是mrc下的assign声明
@property (nonatomic, assign) Student *stu1;
接下来初始化一个Student对象,并且敲入以下代码
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. Student *stu = [[Student alloc] init]; stu.name = @"张三"; self.stu1 = stu; NSLog(@"%p %p", &stu, &_stu1); NSLog(@"%p %p", stu,_stu1); self.stu1.name = @"李四"; NSLog(@"stu.name = %@", stu.name); NSLog(@"stu的引用计数 = %ld", [stu retainCount]); }控制台输出
(一)所以我总结,assign只是使指向stu的栈内存上的的指针,也就是stu换了一个名字,换成了stu1,就是stu和stu1的作用和意义是一样的,谁做了任何改变对应的指向栈内存的内容也会随之改变,但是栈内存的引用计数还是1没有增加。
接下来我们看看retain,改变stu1属性为以下
@property (nonatomic, retain) Student *stu1;
然后重新运行程序控制台输出为:
(二)再来总结一下,retain是使指向栈内存的指针多了一个,也就是引用计数加1,并且指针stu和stu1对于栈内存的作用是一样的,也就是一扇门多了一把钥匙
接下来再看看copy的作用,同样改变stu属性为copy,但是如果是我们定义的对象,那么我们自己要实现NSCopying,这样就能调用copy,贴出代码
Student.h
#import <Foundation/Foundation.h> @interface Student : NSObject<NSCopying> @property (nonatomic, copy) NSString *name; @endStudent.m
#import "Student.h" @implementation Student - (id)copyWithZone:(NSZone *)zone { <p class="p1"><span class="s1"> </span><span class="s2">Student</span><span class="s1"> *stuCopy = [[</span><span class="s3">self</span><span class="s1"> </span><span class="s4">class</span><span class="s1">] </span><span class="s4">allocWithZone</span><span class="s1">:zone];</span></p><p class="p1"><span class="s1"> stuCopy.</span><span class="s5">name</span><span class="s1"> = [</span><span class="s3">self</span><span class="s1">.</span><span class="s5">name</span><span class="s1"> </span><span class="s4">copyWithZone</span><span class="s1">:zone];</span></p><p class="p1"><span class="s1"> </span><span class="s3">return</span><span class="s1"> stuCopy;</span></p>} @end
viewDidLoad里的代码不变,运行程序,控制台输出
(三)可以看出,stu.name没有改变,而且stu的引用计数没用增加,为什么呢?因为copy是完全复制一段栈内存,所以copy出来的对象与原来的对象是两个不同地址的对象,所以对于stu没有影响
好了,接下来我们看看arc模式下,strong和weak的区别及用法.
先是strong,声明属性
@property (nonatomic, strong) Student *stu1;
viewDidLoad中的代码
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. Student *stu = [[Student alloc] init]; self.stu1 = stu; NSLog(@"%p %p", &stu, &_stu1); NSLog(@"%p %p", stu, _stu1); stu = nil; NSLog(@"将stu滞空之后"); NSLog(@"%p %p", &stu, &_stu1); NSLog(@"%p %p", stu, _stu1); }控制台输出
(四)可以看出,当将stu赋值给stu1之后,这两个指针指向的栈内存是一样的,也就是说这里和retain是一样的,但是当我们将stu滞空后,stu1指向的栈内存并没有变为空,这就是strong与retain的区别,当栈内存只要有两个或者两个以上指针指向的时候,对其中指针进行滞空操作都不会释放掉栈内存,也就是strong出来的对象,对于栈内存有控制权,还有一点,arc下默认的赋值方式就是strong
接下来,我们看看weak
其他都一样,把stu1属性改为weak,运行程序,控制台输出
(五)可以看出,当将stu赋值给stu1之后,这两个指针指向的栈内存是一样的,也就是说这里和retain是一样的,但是当我们将stu滞空后,stu1指向的栈内存变为空,这就是weak与strong的区别,也就是weak出来的对象,对于栈内存没有控制权
这里说一下,为什么不用NString测试,因为NString *str = @“dddd”,然后str = @“bbbb”,是新开辟一个栈内存来存放“bbbb”不是在原有的基础上改的。
用string做retain测试,大家会发现,无论怎么样retain,但是改变其中一个变量后,另一个不变。
相关文章推荐
- iOS 设计模式-委托模式
- 『iOS/Obj-C』Note Of 8-day Obj-C/iOS foundation course
- iOS概念入门学习-OC-类的继承和派生
- igrimaceV8.0.0 IG 一键新机 陌陌 Uber优步打针 平安易贷 滴滴 一号专车 饿了么 ios8 V8 ZTN(插件安装方式)
- iOS 播放音频的几种方法
- ios日期格式转换
- iOS 设置所有的按钮的selected状态为NO
- IOS之正则表达式
- iOS Auto Layout学习
- iOS中button上得文字右对齐
- IOS公司开发者账号申请详细教程
- **ios提交应用加急审批**
- IOS OC 多态(白话)
- **IOS开发之关键字category(类别)详解**
- iOS中nil,Nil,NULL的区别
- iOS 学习之 NSPredicate 模糊、精确、查询
- iOS系统定位权限弹出框和跳转系统设置页面的调研
- 常见的选择<数据源协议,委托协议>(IOS发展)
- iOS 委托和协议
- IOS 自动约束