OC内存管理教程之ARC(三)——与@property的羁绊
来源:互联网 发布:有源码怎么做辅助 编辑:程序博客网 时间:2024/05/02 02:01
前言:
有了前两篇的基础,那么对内存管理已经有了大体的认识了。但知道了原理,还要明白怎么应用,前两篇使用的例子都是极其简单的,能最直观体现特性的,在做ios开发时,创建类,声明属性都更复杂,那么这时候内存管理是怎么应用呢?这篇就是来介绍这样的内容。
类Class中的属性property
一般在ios开发中,自己实现一个继承于UIView(或者其他UI空间)的类时,声明属性都不会像前两篇的那样那么简单。不管是storyboard开发,还是纯coder,在声明属性的时候都是写成@property(.....)这样的形式,因为我们需要编译器为我们为这个属性生成set方法和get方法。
在ios第一版中,我们为输出口同时声明了属性和底层实例变量,那时,属性是oc语言的一个新的机制,并且要求你必须声明与之对应的实例变量,例如:
@interface MyViewController :UIViewController{ UIButton *myButton;}@property (nonatomic, retain) UIButton *myButton;@end对于.m文件:
@synthesize myButton;这样写了之后,那么编译器会自动生成myButton的实例变量,以及相应的getter和setter方法。
而大概是在13年的时候,苹果将默认编译器从GCC转换为LLVM(low level virtual machine),从此不再需要为属性声明实例变量了。如果LLVM发现一个没有匹配实例变量的属性,它将自动创建一个以下划线开头的实例变量。因此,在这个版本中,我们不再为输出口声明实例变量。
例如:MyViewController.h文件:
@interface MyViewController :UIViewController@property (nonatomic, retain) UIButton *myButton;@end在MyViewController.m文件中,如果写了@synthesize myButton;那么生成的实例变量就是myButton;如果没写@synthesize myButton;那么生成的实例变量就是_myButton。所以跟以前的用法还是有点细微的区别。当然一般都是不写的,使用生成的_myButton。那么在.m文件中可以直接的使用_myButton实例变量,也可以通过属性self.myButton.都是一样的。
注意这里的self.myButton其实是调用的myButton属性的getter/setter方法。这与C++中点的使用是有区别的,C++中的点可以直接访问成员变量(也就是实例变量)。
例如在oc中有如下代码
.h文件
@interface MyViewController :UIViewController{ NSString *name;}@end.m文件中,self.name 这样的表达式是错误的。xcode会提示你使用->,改成self->name就可以了。因为oc中点表达式是表示调用方法,而上面的代码中没有name这个方法。
oc语法关于点表达式的说明:"点表达式(.)看起来与C语言中的结构体访问以及java语言汇总的对象访问有点类似,其实这是oc的设计人员有意为之。如果点表达式出现在等号 = 左边,该属性名称的setter方法将被调用。如果点表达式出现在右边,该属性名称的getter方法将被调用。"
所以在oc中点表达式其实就是调用对象的setter和getter方法的一种快捷方式, 例如:dealie.blah = greeble 完全等价于 [dealie.blah setBlah:greeble];
@property关键字
经常可以看到类似这样的写法:
@property(nonatomic,readonly,retain) UINavigationItem *navigationItem;@property(nonatomic) BOOL hidesBottomBarWhenPushed;@property(nonatomic,readonly,retain) UINavigationController *navigationController;不同类别的属性,@property里的关键字也不一样。@property的常用属性关键字有nonatomic、atomic、readonly、writeonly、readwrite、assign、retain、copy、strong、weak、unsafe_unretained、nonnull、nullable、null_resettable,看着挺多的,但是经常用的也就那几个。
1、第一个位置的值,原子关键字:
atomic:线程保护的,默认。
nonatomic:线程不保护的。
2、第二个位置的值,所有权关键字:
assign: 默认关键字。非对象类型一般使用此关键字。
retain: 对象的引用计数+1。ARC下已经不再使用此关键字,用strong代替。
copy: 拷贝一个新的对象,新对象的引用计数+1,原对象不变。
strong: 能够维持对象的生命。
3、第三个位置的值,读写关键字:
readwrite:生成get/set方法,默认。
readonly:只生成get方法。
对于第二个位置的关键字,它们和一般声明属性时所使用的修饰符有以下的对应关系:
此外,作为ios开发,常常能听到或者学习到类似这样的总结:
- 用strong修饰OC对象、没添加到父控件上的控件
- 用weak修饰已经被添加到父控件上的UI控件、代理对象
- 用assign修饰基本数据类型(int float bool等)、枚举、结构体(非OC对象)、class类型
- 用copy修饰一种情况下的NSString-->不确定赋值过程中用的是可变还是不可变字符串、block
UI控件、代理对象用weak
@interface ViewController()@property(nonatomic,weak) UIButton *btnA;@end使用情况一般如下
- (void)viewDidLoad { [super viewDidLoad]; UIButton *btnA = [[UIButton alloc] init];//创建一个UIButton _btnA = btnA;//让属性指向这个UIbutton。注意_btnA才是上面@property声明的属性 //配置btnA的各个参数 [self.view addSubview:_btnA]; }可以用图来解释:
当调用方法[self.view addSubview:_btnA]时,整个应用程序就会参数如下的引用关系(强指针用实线表示,弱指针用虚线表示):
OC对象用strong
@interface ViewController()@property(nonatomic,strong) NSObject *obj;@end
- (void)viewDidLoad { [super viewDidLoad]; NSObject *obj = [[NSObject alloc] init]; _obj = obj; }
NSString、NSMutableString、NSArray、NSMutableArray用copy
首先介绍一个简单的概念:深拷贝与浅拷贝
浅拷贝:把指针地址复制,就是日常的等号赋值操作的效果。两个变量指向同一个对象。
深拷贝:把指针指向的对象在内存中复制一份,然后把新产生的对象的指针赋值。两个变量指向不同对象,但这两个对象的内容一致。
而copy关键字,就能保证等号赋值的时候,编译器帮我们做一次深拷贝。如此就能理解为什么这些对象要用copy关键字了。
copy只是不可变拷贝,而mutableCopy是可变拷贝。比如,NSArray *arr = [modelsArray copy],那么arr是不可变的。而NSMutableArray *ma = [modelsArray mutableCopy],那么ma是可变的。
总结:
终于把内存管理系列的三篇文章写完了,自我感觉还是挺良好的,觉得是个不错的教程。写文章的时候,也补足了自己很多原来理解上的漏洞或者缺乏的地方,对内存管理有了更深刻的认识。也希望这系列的教程能给读者们带来启发。
- OC内存管理教程之ARC(三)——与@property的羁绊
- OC内存管理教程之ARC(一)——objective-c内存管理和引用计数
- OC内存管理教程之ARC(二)——自动引用计数规则
- OC内存管理之ARC
- iOS OC内存管理、ARC、property属性、__strong、__weak、__block——iOS 编码复习(一)
- OC @property的内存管理
- OC内存管理 MRC与ARC
- oc的ARC的内存管理
- OC的内存管理方式----MRC & ARC
- OC加强day1-内存管理的范围、MRC与ARC、property参数,retain死循环、NSSstring简解、自动释放池、堆栈等得存储方式
- 黑马程序员——OC——ARC内存管理
- 黑马程序员——OC——ARC内存管理
- 黑马程序员——OC语言------内存管理和ARC
- 黑马程序员——OC的内存管理——ARC
- OC基础—内存管理之@property及其参数(补充新知识:循环引用和@class)
- iOS内存管理与ARC,及Property介绍
- OC内存管理(ARC)
- OC-025.OC手动MRC内存管理@property的使用方法
- 扩展KMP
- iOS开发最简单的用一组图片形成动态效果
- 机器语言(即01010),你真的理解吗?
- 高效开发者之思维模式
- Matlab一个错误引发的血案:??? Error using ==> str2num Requires string or character array input
- OC内存管理教程之ARC(三)——与@property的羁绊
- 深入解析指针数组和数组指针
- 用两个队列实现栈(C++模板)
- spring MVC 文件上传下载的实现
- Java并发编程实战2-线程安全
- Microsoft牛津计划——文本分析
- httpUtils
- ASP.NET Core MVC 配置全局路由前缀
- 使用java技术将数据导出到excel中