码迷,mamicode.com
首页 > 其他好文 > 详细

OC08,09-内存管理

时间:2015-07-28 21:12:25      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:ios   oc   内存管理   

内存管理

介绍

管理内存的常见方式

1.垃圾回收:java常见的管理内存的方式,系统来检测对象是否被使用,是否被释放

2.MRC手动管理引用计数,iOS管理内存的方式,程序员通过手动的方式来管理对象是否被释放

3.ARC自动管理引用计数,基于MRC,系统自动的管理内存,以后我们还是先使用MRC,培养管理内存的习惯

内存常见问题

  • 内存溢出
  • 野指针异常

iOS的内存管理

  • ARC
  • MRC

其中,MRC的内存管理机制是引用计数

内存管理机制

OC采用引用计数的机制,即一个新的引用指向对象的时候,引用计数器(retainCount)就递增,当释放掉一个引用的时候,计数器就递减.到0的时候调用dealloc,即释放占有的资源

影响引用计数的方法

+alloc

    // 对象被创建出来之后,他的引用计数retainCount就变成1
    Boy *boy = [[Boy alloc] init];
    NSLog(@"%ld",boy.retainCount);

结果:

2015-07-28 18:45:45.361 OC08,09_内存管理[2694:166290] 1

-retain

// retain:对对象的引用计数进行+1的操作
    [boy retain];
    [boy retain];
    [boy retain];
    NSLog(@"%ld",boy.retainCount);

结果:

2015-07-28 18:45:45.361 OC08,09_内存管理[2694:166290] 4

-release

    [boy release];
    NSLog(@"%ld",boy.retainCount);
    [boy release];
    [boy release];
    [boy release];

结果:
(最后是因为在类中声明了dealloc)

2015-07-28 19:04:21.023 OC08,09_内存管理[2721:171301] 3
2015-07-28 19:04:21.024 OC08,09_内存管理[2721:171301] 对象被释放

注意:当对象的引用计数1 -> 0的时候,会自动调用dealloc方法.dealloc才是对应对象释放的方法,并且注意,如果多次对对象进行release释放,会造成过度释放,过度释放也是最常见的内存问题.

当对象调用release的时候,它的引用计数是1,这个对象就不在对它的引用计数进行 -1 操作,而是直接调用dealloc方法,所以,在访问对象的引用计数的时候还是1

-autorelease

    Boy *boy = [[Boy alloc] init];

    [boy retain];
    [boy retain];
    NSLog(@"%ld",boy.retainCount);

    // release马上会把对象的引用计数-1,但是autorelease会延迟对对象的计数-1
    // 自动释放池
    // 只要对象用autorelease释放,会把对象放入到系统的自动释放池中,等出了池子的范围,对象引用计数自动-1,这个相当于java的垃圾回收,对象释放由系统来管理
    @autoreleasepool {
        [boy autorelease];
        NSLog(@"%ld",boy.retainCount);
    }
    NSLog(@"%ld",boy.retainCount);

-copy
copy也可以改变引用计数,但是他改变的是新对象的引用计数,而原先的对象计数不变

    NSArray *arr = @[@"1",@"2",@"3",@"4"];
    NSLog(@"%ld",arr.retainCount);
    NSArray *newArr = [arr copy];
  NSLog(@"%ld",newArr.retainCount);

结果:

2015-07-28 19:35:46.831 OC08,09_内存管理[3016:189709] 1
2015-07-28 19:35:46.832 OC08,09_内存管理[3016:189709] 2

内存管理的原则

凡是使用了alloc、retain或者copy让内存的引用计数增加了,就需要使用release或者autorelease让内存的引用计数减少。在一段代码内,增加和减少的次数要相等。

注意:便利构造器在返回对象的时候会加上一个autorelease,所以用便利构造器创建的对象不需要对内存进行内存管理

copy

跟retain不同,一个对象想要copy,生成自己的副本,需要实现 NSCopying协议,定义copy的细节(如何copy)。如果类没有接受NSCopying协议而给对象发送copy消息,会引起crash。

copy方法的实现

Boy.m

- (id)copyWithZone:(NSZone *)zone
{
    Boy *b = [Boy allocWithZone:zone];

    b.hobby = _hobby;
    b.name = _name;

    return b;
}

版权声明:本文为博主原创文章,转载请注明原文地址

OC08,09-内存管理

标签:ios   oc   内存管理   

原文地址:http://blog.csdn.net/u011752406/article/details/47110403

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!