黑马程序员_OC学习之内存管理
来源:互联网 发布:live2d mac有哪些 编辑:程序博客网 时间:2024/05/18 20:12
前言:OC中凡是手动建立的对象都需要我们自己管理内存,这些对象被分配到堆中。每个对象都有自己的引用计数器,如果计数器变为0,那么对象就被销毁,下面是OC中一系列关于内存方面的知识总结。
一、内存管理:
关于内存方面有几个关键词:1、retain、copy:使对象引用计数器加一;
2、release:释放一次,引用计数器减一;
3、alloc:创建新对象,默认引用技术器为一;
4、dealloc方法:当对象消亡时,会调用该方法。
例如:
<span style="font-size:18px;">#import <Foundation/Foundation.h>@interface Person : NSObject@end@implementation Person- (void)dealloc { NSLog(@"Person dead"); //当对象消亡,会调用这个方法 [super dealloc];}@endint main() { Person *p = [[Person alloc]init]; //这时p这个指针指向的对象默认引用计数器+1; [p retain]; //p指向的对象引用计数器+1 [p release]; //计数器-1 [p release]; //当p指向的对象计数器为0时,对象消亡; return 0; }</span>
----------------------------------------------------------------------------------------------------------------------------------------------------------
二、@property参数:
先看一段代码:
<span style="font-size:18px;">#import <Foundation/Foundation.h>@interface Dog : NSObject@end@interface Person : NSObject{ Dog *_dog;}- (void)setDog:(Dog *)dog;@end@implementation Person- (void)dealloc { [_dog release]; //当人死亡时,把狗也杀了(太不道德了。。) NSLog(@"Person dead"); //当对象消亡,会调用这个方法 [super dealloc];}- (void)setDog:(Dog *)dog { if (dog != _dog) { //如果这条狗不是新领养的那一条 [_dog release]; //对原来那条释放 _dog = [dog retain]; //再对新狗保留所有权 }}@end@implementation Dog- (void)dealloc { NSLog(@"Dog dead"); [super dealloc];}@endint main() { Person *p = [[Person alloc]init]; //这时p这个指针指向的对象默认引用计数器+1; Dog *d1 = [[Dog alloc]init]; Dog *d2 = [[Dog alloc]init]; p.dog = d1; //当人第一次养狗时,需要retain一下,意味获取狗的所有权。 p.dog = d2; //人换了一条狗,那么就需要对原来那条狗释放 [d2 release]; [d1 release]; [p release]; //当p指向的对象计数器为0时,对象消亡; return 0; }</span>
根据例子我们知道,为了程序的严谨,我们会在set方法中加入一些代码,防止内存泄露。为了节省时间,可以为@property添加几个参数:
1、set方法内存管理相关的参数
retain:release旧值,retain新值(适用于OC对象类型)
assign:直接赋值(默认。适用于非OC对象类型)
copy:release旧值,copy新值
2、是否生成set方法
readwrite:同时生成setter和getter的声明、实现
readonly:只会生成getter的声明、实现
3、多线程管理
nonatomic:无原子操作,性能高
atomic:原子操作,保证数据正确,性能低(默认)
4、setter和getter方法的名称
setter:决定了set方法的名称,一定要有冒号:
getter:决定了get方法的名称(一般用在BOOL类型)
5、ARC补充(在下面做介绍)
strong:强指针,替换retain
weak:弱指针,相当于assign,但用于OC对象
例如:
<span style="font-size:18px;">#import <Foundation/Foundation.h>@interface Dog : NSObject@end@interface Person : NSObject@property (nonatomic, retain) Dog *dog; //会自动生成上面例子中setter的代码@end@implementation Person- (void)dealloc { [_dog release]; //当人死亡时,把狗也杀了(太不道德了。。) NSLog(@"Person dead"); //当对象消亡,会调用这个方法 [super dealloc];}@end@implementation Dog- (void)dealloc { NSLog(@"Dog dead"); [super dealloc];}@endint main() { Person *p = [[Person alloc]init]; Dog *d1 = [[Dog alloc]init]; Dog *d2 = [[Dog alloc]init]; p.dog = d1; p.dog = d2; [d2 release]; [d1 release]; [p release]; return 0; }</span>
----------------------------------------------------------------------------------------------------------------------------------------------------------
三、循环引用:
当两个对象A包含B,B包含A时会引发循环引用,谁也不会被销毁,这时我们需要对其中一个做assign,另一个做retain
例如:
<span style="font-size:18px;">#import <Foundation/Foundation.h>@class Person; //提前声明,告诉Dog,这个Person其实是一个类@interface Dog : NSObject@property (nonatomic,assign) Person *person;@end@interface Person : NSObject@property (nonatomic, retain) Dog *dog; //会自动生成上面例子中setter的代码@end@implementation Person- (void)dealloc { [_dog release]; //当人死亡时,把狗也杀了(太不道德了。。) NSLog(@"Person dead"); //当对象消亡,会调用这个方法 [super dealloc];}@end@implementation Dog- (void)dealloc { NSLog(@"Dog dead"); [super dealloc];}@endint main() { Person *p = [[Person alloc]init]; Dog *d = [[Dog alloc]init]; p.dog = d; d.person = p; [d release]; [p release]; return 0; }</span>
----------------------------------------------------------------------------------------------------------------------------------------------------------
四、autorelease:
OC会在程序运行时创建若干个自动释放池,并把它们放到一个栈中,我们可以把一个对象放到其中,当用在对象后加上autorelease时,代表它会把该对象放到栈顶的池子中。随着一个自动释放池被销毁,它会将它里面的对象做一次release操作。
例如:
<span style="font-size:18px;">#import <Foundation/Foundation.h>@class Person; //提前声明,告诉Dog,这个Person其实是一个类@interface Dog : NSObject@property (nonatomic,assign) Person *person;@end@interface Person : NSObject@property (nonatomic, retain) Dog *dog; //会自动生成上面例子中setter的代码@end@implementation Person- (void)dealloc { [_dog release]; //当人死亡时,把狗也杀了(太不道德了。。) NSLog(@"Person dead"); //当对象消亡,会调用这个方法 [super dealloc];}@end@implementation Dog- (void)dealloc { NSLog(@"Dog dead"); [super dealloc];}@endint main() { @autoreleasepool { Person *p = [[[Person alloc]init]autorelease]; Dog *d = [[[Dog alloc]init]autorelease]; p.dog = d; d.person = p; } //当池子被销毁,里面的对象会做一次release操作 // [d release]; //不需要release,因为我们d与p两个对象都在自动释放池中// [p release]; return 0; }</span>
注意:当我们想准确操作一个对象的“生死”时,不要把它放到自动释放池中,它只适用于小数据的自动释放。
----------------------------------------------------------------------------------------------------------------------------------------------------------
五、ARC机制:(Automatic Reference Counting)
ARC属于编译时的机制,它会检查一个对象是否有强指针指向它,如果没有,它会在后面加上release代码。这点区分于JAVA的垃圾回收机制,JAVA程序会在程序运行时检测一个对象是否有指针指向,如果没有那么就会将对象作为垃圾回收。
解释一下@property中两个参数:
1、strong:声明对象为强指针(默认)
2、weak:声明对象为弱指针,当它指向的一个对象,同时没有其他强指针指向时,会被ARC添加release代码,该对象会被回收,这个弱指针也会自动被赋值为nil,所以弱指针不能单独指向对象。
例如:
<span style="font-size:18px;">#import <Foundation/Foundation.h>@class Person; //提前声明,告诉Dog,这个Person其实是一个类@interface Dog : NSObject@property (nonatomic,strong) Person *person; //retain变为strong@end@interface Person : NSObject@property (nonatomic, weak) Dog *dog; //防止循环引用,assign变成weak@end@implementation Person- (void)dealloc { NSLog(@"Person dead");}@end@implementation Dog- (void)dealloc { NSLog(@"Dog dead");// [super dealloc ]; //这句会被报错}@endint main() { Person *p = [[[Person alloc]init]autorelease]; Dog *d = [[[Dog alloc]init]autorelease]; p.dog = d; d.person = p; // [p release]; //有了ARC,所有关于内存方面的关键字都不会再被使用。// [d release]; return 0; }</span>
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------详细请查看:www.itheima.com
- 黑马程序员_OC学习之内存管理
- 黑马程序员_OC学习之内存管理
- 黑马程序员学习笔记_OC之内存管理1
- 黑马程序员学习笔记_OC之内存管理 2
- 黑马程序员学习笔记_OC之内存管理3ARC
- 黑马程序员_OC之内存管理
- 黑马程序猿_OC之内存管理
- 黑马程序员-----OC学习之内存管理
- 20150618_OC之内存管理
- 黑马程序员:OC学习日记之内存管理
- 黑马程序员——OC学习之内存管理ARC
- 黑马程序员-----oc语言学习笔记之内存管理一
- 黑马程序员-----oc语言学习笔记之内存管理二
- 黑马程序员-----oc语言学习笔记之内存管理三
- 黑马程序员----Objective-C学习笔记之内存管理
- 黑马程序员复习-重点之内存管理
- 黑马程序员--OC之内存管理
- 黑马程序员--OC之内存管理
- spring组件扫描<context:component-scan/>使用详解
- 关于hibernate与spring整合
- JavaScript函数表达式与函数声明的区别
- vs2008 如何创建windows应用程序项目
- java.lang.OutOfMemoryError: Java heap space解决方法
- 黑马程序员_OC学习之内存管理
- 常用协议
- throws与throw区别
- seo的思维与头脑风暴
- SHELL if
- WPF ProgressBar显示进度(五)
- struts2源码探索之初始化(三)
- 【Jqurey EasyUI+Asp.net】---- datagrid 绑定数据库(SQL)
- 程序在Debug、Release下运行及单独运行Debug下的exe文件时没有问题;可是单独运行Release所生成的exe文件时,点击某一个按钮时,程序崩溃