zoukankan      html  css  js  c++  java
  • iOS中的retainCount

          我们都知道iOS中采用引用计数的技术来管理内存,当一个对象没有任何一个地方引用的时候会自动释放,此时的retainCount为0,而且提供了一个-(NSInteger)retainCount的方法来获得对象当前的持有数。

         这个概念清楚而明确,不过,让我们看两段代码:

        NSNumber *number = [NSNumber numberWithInt:1];
        NSLog(@"retainCount = %lu",[number retainCount]);

          这段代码的运行结果是什么?

        NSString *string = [NSString stringWithFormat:@"foo"];
        NSLog(@"retainCount = %lu", [string retainCount]);

          这一段呢?

          在Xcode5.0, ARC关闭的情况下运行,结果是:

    2014-01-13 22:08:13.217 blockTest[2732:303] retainCount = 9223372036854775807

    2014-01-13 22:08:13.218 blockTest[2732:303] retainCount = 1

          这个很出人意料啊,第二段看上去很符合我们的预期,但第一段就有点让人掉眼镜了。

          查阅了一下官方的文档,第一句就是“Do not use this method.”,后面给出了说明,因为Autorelease pool的存在,对于内存的管理会相当复杂,retainCount就不能用作调试内存时的依据了。这样对于第一段的结果就可以理解了,可能系统对于这一个特殊的对象有特殊的处理(没准framework里面有早就创建了这个对象了),于是我们拿到了一个非常出人意料的结果。

          想想见过的如下的代码就很有点吓人了:

        while ([a retainCount] > 0) {
            [a release];
        }
          如果运行结果正确,那么这是多么幸运的一个人啊!

          但对于内存的思考我们可以更进一步,看一段代码:

    #import <Foundation/Foundation.h>
    
    @interface Person : NSObject
    
    @property(nonatomic, retain) NSString *name;
    @property(nonatomic, assign) NSInteger age;
    
    @end
    
    @implementation Person
    - (id)init
    {
        self = [super init];
        if (self) {
            self.name = @"name";
            self.age = 20;
        }
        return self;
    }
    
    - (void)dealloc
    {
        NSLog(@"dealloc");
        [super dealloc];
    }
    
    @end
    
    int main(int argc, const char * argv[])
    {
        Person *per1 = [[Person alloc] init];
        //NSLog(@"retainCount = %lu -- 0",[per1 retainCount]);
        [per1 release];
        per1.age = 22;
        NSLog(@"retainCount = %lu -- 1, age = %ld",[per1 retainCount], per1.age);
        //[per1 retain];
        //per1.age = 23;
        //NSLog(@"retainCount = %lu -- 2, age = %ld",[per1 retainCount], per1.age);
        
        return 0;
    }
          这段代码的运行结果居然是:

    2014-01-13 22:17:11.619 blockTest[2758:303] dealloc

    2014-01-13 22:17:11.621 blockTest[2758:303] retainCount = 1 -- 1, age = 22

          这个问题位于http://www.cocoachina.com/ask/questions/show/106777#36483,个人猜测是对象确实销毁了,毕竟dealloc都调用了,但内存里面数据仍然存在,立刻打印是存在内容的,至于retainCount不是0,只能说明对象即使已经销毁了,这个值仍然可能大于0。

  • 相关阅读:
    HTML页面保存为图片
    一些chrome调试
    hooks使用的一些注意点
    React(v16.8) Hooks 简析
    基于 React.js 和 Node.js 的 SSR 实现方案
    移动端垂直居中对齐
    python XML ElementTree的增删改查
    python实现XML解析的三种方法
    git的用法
    Appium获取元素的方式
  • 原文地址:https://www.cnblogs.com/huluo666/p/3645893.html
Copyright © 2011-2022 走看看