黑马程序员---OC内存管理中的MRC

来源:互联网 发布:c语言中的数据类型 编辑:程序博客网 时间:2024/05/23 13:06

OC内存管理的范围

管理任何继承NSObject的对象,对其他的基本数据类型无效。

OC内存管理分类 

1)

MannulReference Counting(MRC,手动管理,在开发iOS4.1之前的版本的项目时我们要自己负责使用引用计数来管理内存,比如要手动 retain、release、autorelease 等,而在其后的版本可以使用 ARC,让系统自己管理内存。)

2)

automatic reference counting(ARC,自动引用计数,iOS4.1之后推出的) 

手动内存管理应遵守以下原则:

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 intage;
@end

Person.m

#import "Person.h"

@implementation Person

//对象是否被回收的方法

-(void)dealloc{

//释放子类对象

NSLog(@"对象被销毁了~");

//释放父类
[superdealloc];

}

@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 allocinit];

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对象不会释放,这是就造成了内存泄漏,使用手动内存管理要特别小心。一般使用

自动内存管理。


0 0
原创粉丝点击