OC基础-内存管理
来源:互联网 发布:excel数据分行显示 编辑:程序博客网 时间:2024/05/08 04:53
<1>内存管理的概念:由于移动设备的内容极其有限,所以对其中无用的内存空间要进行及时回收,这称为内存管理。
内存管理的范围:所有继承至NSObject的对象,其中基本数据类型由系统自动进行管理。
内存管理的原理:当在栈区定义类的实例变量后,该变量就是该实例变量的一个所有者。实例化的类对象中有retainCount变量,
称为对象的引用计数器。当引用计数器为0时,就会调用对象的dealloc方法进行对象内存空间的释放。
内存管理的分类:(1)ARC(AutoReferenceCounting):自动内存管理;(2)MRC(ManualReferenceCounting):手动内存管理;
在MRC下,可以通过对象的retain方法使retainCount增加1,release方法使retainCount减少1;当对象释放其所占用的内存空间时,
会自动调用自身的dealloc方法,可以在NSObject中重写dealloc方法。
<2>内存管理的原则:(1)谁创建,谁release;(2)谁retain,谁release。(2)只要存在对象的所有者,对象就不会被回收。
内存管理研究的内容:(1)野指针。当指针变量未初始化,或者指针变量所指向的内存空间被释放时,都会出现野指针。(2)内存泄露:
栈区的变量已经释放,而堆区的内存空间未释放时,就会出现内存泄露。
<3>单个对象的内存管理:nil:指向实例对象;Nil:指向类对象;null:指向实例对象,用在不能使用nil的场所。
给nil发送任何消息都没有效果,但能通过编译器检查。
单个对象内存泄露的情况:(1)创建完成后,没有release;(2)没有遵守内存管理的原则;(3)不当的使用了nil;(4)在函数中retain.
<4>多个对象的内存管理:依赖关系的两个对象,其正确的属性setter方法如下:
@interfance Car:NSObject
@end
@interface Person:NSObject
{Car *_car;}
-(void)setCar:(Car *)car;
@end
@implementation
-(void)setCar:(Car *)car{
if(_car != car){//避免出现僵尸对象复活的错误
[_car release];//避免出现内存泄露
_car = [car retain];//避免出现僵尸对象引用的错误
}
}
@end
<5>@property的参数有三种:
(1)原子性。
atomic:对属性加锁,多线程安全,是property的默认值;nonatomic:对属性不加锁,多线程
不安全,但速度快;
(2)读写性。
readwrite:具有完整的setter和getter方法;
readonly:只有getter方法;
(3)setter方法的处理:
assign:简单地直接赋值,是property的默认方法;
retain:对实例变量先release,再retain;
copy:对实例变量先release,在retain;
可以在@property的参数中给setter或者getter方法制定别名,如
@interface Person :NSObject
@property (nonatomic,assign ,setter = isSolider: ) BOOL solider;//指定setter方法别名为isSolider;
@end
Person *p = [Person new];
[p isSolider] = YES;//在main函数中使用isSolider方法对属性进行赋值;
<6>@class的应用:简单的引用类,告诉编译器一个类对象,并不进行类属性和方法的检查。
使用注意:(1)在.h文件中 声明@class XX;(2)在.m文件中,引用#import “XX.h”;
特殊用法:可以解决#import循环引用的问题;
@class和#import的区别:
(1)作用上:@class进行类的简单引用,而#import则是把引用文件拷贝到它所在的位置;
(2)效率上:@class引用避免了引用文件修改时的及时更新,效率较高;
<7>循环retain的问题:当两个对象循环retain时,会导致内存泄露。
防止方法:(1)在执行结束时,让其中某个对象再release一次;
(2)循环retain的两方,一端使用assign,一端使用retain;
<8>NSString类的内存管理问题:用@”XX“,[NSString StringWithString:@“XX”],[[NSString alloc] init]方法定义的字符串都是
存在内存中的常量区(数据区),当在栈区定义新的字符串变量时,如果在常量区中存在,则系统不会再次分配空间,而是会将变量指向已经
存在的变量;
用[NSString StringWithFormat:@“”]方法定义的字符串变量存放在堆区,需要对其进行内存释放;
<9>autorelease的基本使用。
(1)特殊的栈结构;
(2)对象调用autorelease方法时,会被放在栈顶;
(3)当内存池排干(drain)时,会对其中的对象发送release消息。
其中内存管理的几个实例代码如下:
(1)
#import <Foundation/Foundation.h>@interface Person : NSObject-(void)eat;@end#import "Person.h"@implementation Person-(void)dealloc{ NSLog(@"人已经被处理了"); [super dealloc];}-(void)eat{ NSLog(@"人在吃饭");}@end#import <Foundation/Foundation.h>#import "Person.h"//验证内存管理的原则:谁retain,谁releaseint main(int argc, const char * argv[]) { @autoreleasepool { Person *p = [Person new]; NSLog(@"retainCount = %ld",[p retainCount]); Person *p1 = [p retain]; NSLog(@"retainCount = %ld",[p retainCount]); [p1 release]; [p1 eat]; NSLog(@"retainCount = %ld",[p retainCount]); [p release]; [p eat]; } return 0;}
2
<p style="margin-top: 0px; margin-bottom: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(228, 68, 72);"><pre name="code" class="objc">#import <Foundation/Foundation.h>#include "Car.h"@interface Person : NSObject{ Car *_car;}-(void)setCar:(Car *) car;-(void)drive;@end#import "Person.h"@implementation Person-(void)setCar:(Car *) car{ if (_car != car) { [_car release]; _car = [car retain]; }}-(void)drive{ [_car run];}-(void)dealloc{ [_car release]; NSLog(@"人已经挂了"); [super dealloc];}@end#import <Foundation/Foundation.h>@interface Car : NSObject@property int speed;-(void)run;@end#import "Car.h"@implementation Car@synthesize speed;-(void)run{ NSLog(@"车以%d的速度奔跑!",self.speed);}-(void)dealloc{ NSLog(@"车已经挂了"); [super dealloc];}@end//关联对象的内存管理#import <Foundation/Foundation.h>#import "Person.h"int main(int argc, const char * argv[]) { @autoreleasepool { Person *p = [Person new]; Car *car = [Car new]; car.speed = 18; [p setCar:car]; [car release];//清除car空间 [p drive];// [p release];//清除person空间 } return 0;}3
<pre name="code" class="objc" style="color: rgb(228, 68, 72); font-size: 13px;"><pre name="code" class="objc">#import <Foundation/Foundation.h>@class Person;@interface Dog : NSObject@property (nonatomic,assign) Person *owner;@end#import "Dog.h"@implementation Dog-(void)dealloc{ // [_owner release]; NSLog(@"dog dealloc"); [super dealloc];}@end#import <Foundation/Foundation.h>#import "Dog.h"@interface Person : NSObject@property (nonatomic,retain)Dog *dog;@end#import "Person.h"@implementation Person-(void)dealloc{ [_dog release]; NSLog(@"Person dealloc"); [super dealloc];}@end//@class避免循环引用#import <Foundation/Foundation.h>#import "Person.h"int main(int argc, const char * argv[]) { @autoreleasepool { Person *p = [Person new]; Dog *d = [Dog new]; p.dog = d; d.owner = p; [p release]; [d release]; } return 0;}
<p style="margin-top: 0px; margin-bottom: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(228, 68, 72);"></p>
- OC基础-内存管理
- OC 内存管理基础
- OC基础:内存(内存管理)
- OC基础 -- 内存管理详解
- OC基础:内存结构与内存管理
- 黑马程序员 _9 OC基础 内存管理
- 黑马程序员-IOS-OC基础-内存管理
- OC基础—内存管理之autorelease
- OC基础——内存管理
- 黑马程序员-IOS-OC基础-内存管理
- 黑马程序员------OC基础-----内存管理
- 黑马程序员 OC基础: 内存管理
- OC基础使用(三 内存管理)
- OC 基础之----内存管理总结
- 黑马程序员-OC语言基础:内存管理
- OC基础回顾(八)内存管理
- OC基础-内存管理(三)AutoreleasePool
- [OC基础]手动内存管理
- java.lang.String的 split方法用法总结
- ZZULIOJ 1787 生化危机 (vector+DFS)
- c++虚函数逆向分析
- 网络配置百度地图
- NSURLSession/AFN框架知识点
- OC基础-内存管理
- 水仙花
- S折交叉验证 in Python
- POST
- 开源C/C++网络库比较 ace &&bosst &&libEvent
- 地图定位
- 错排问题-杭电oj1465
- HDU 1209 Clock(模拟)
- LeetCode OJ——Generate Parentheses