OC内存管理的范围
管理任何继承NSObject的对象,对其他的基本数据类型无效。
OC内存管理分类
1)
MannulReference Counting(MRC,手动管理,在开发 iOS4.1之前的版本的项目时我们要自己负责使用引用计数来管理内存,比如要手动 retain、release、autorelease 等,而在其后的版本可以使用 ARC,让系统自己管理内存。)
2)
automatic reference counting(ARC,自动引用计数,iOS4.1 之后推出的)
只要某个对象还在被使用,那么这个对象就不会被回收;只要想使用这个对象,那么就应该让这个对象的引用计数器+1;当不想使用这个对象时,应该让对象的引用计数器-1;
2)
如果你通过alloc,new,copy来创建了一个对象,那么你就必须调用release或者autorelease方法
3)
只要你调用了retain,无论这个对象时如何生成的,你都要调用release
内存管理判断对象被回收的关键是重写dealloc的方法:
- (void) dealloc
{
NSLog(@"车挂掉了");
[super dealloc]
}
1)在这里一定不要直接通过对象调用dealloc方法(实际上调用并不会出错)一旦对象被回收了, 它占用的内存就不再可用, 坚持使用会导致程序崩溃(野指针错误)为了防止调用出错,可以将“野指针”指向nil(0)。
Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject@property int age;
@end
Person.m
#import "Person.h"
@implementation Person
//对象是否被回收的方法
-(void)dealloc{
//释放子类对象
NSLog(@"对象被销毁了~");
//释放父类
[super dealloc];
}
@endmain.m
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *p = [[Person alloc] init];
NSLog(@"p.retainCount = %ld",p.retainCount);
[p retain];
NSLog(@"p.retainCount = %ld",p.retainCount);
[p release];
NSLog(@"p.retainCount = %ld",p.retainCount);
[p release];
}
return 0;
}
运行结果为:
2015-08-05 19:05:41.126 per[2443:234932] p.retainCount = 1
2015-08-05 19:05:41.127 per[2443:234932] p.retainCount = 2
2015-08-05 19:05:41.128 per[2443:234932] p.retainCount = 1
2015-08-05 19:05:41.128 per[2443:234932] 对象被销毁了~
所以在进行手动内存管理时,一定要严格遵守内存管理原则,否则容易出现野指针和内存泄漏
野指针情况:int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *p = [[Person alloc] init];
[p release];//对象空间已经释放
[p setAge:19]//此时的p是个野指针,野称为僵尸对象,所以p不能再使用,回报野指针的错误
}
return 0;
}
内存泄漏情况:
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *p = [ [Person alloc] init];
NSLog(@" p->retainCount = %ld",p.retainCount);//retainCount = 1;
[p retain]; // retainCount = 2;
[p release];//retainCount = 1;
NSLog(@" p->retainCount = %ld",p.retainCount);
}
return 0;
}
由于上面的引用计数不等于0,程序就结束了,p对象不会释放,这是就造成了内存泄漏,使用手动内存管理要特别小心。一般使用自动内存管理。