美文网首页
Autorelease 对象的内存管理

Autorelease 对象的内存管理

作者: TaoGeNet | 来源:发表于2020-02-23 22:02 被阅读0次

    AutoreleasePool 与Runloop 关系

      主线程默认会开启Runloop, Runloop 会自动帮我们创建AutoreleasePool,并进行Push,pop 等操作来进行内存管理。

    ARC 下什么样的对象有autoreleasePool管理

       第一种:当使用alloc/new/copy/mutableCopy 开始的方法进行初始化时,会生成并持有对象(也就是不需要pool管理,系统会在合适的位置release)。对于其他情况,例如:

     id objc = [NSMutableArrayArray array];
    #这种情况会自动将返回值的对象,注册到autoreleasepool,代码等效于
    @autoreleasepool {
      id __autorelease obj = [NSMutableArray array]; 
    }
    

       第二种:__weak 修饰符只持有对象的弱引用,而在访问引用对象的过程中,该对象可能被废弃,那么如果把对象注册到autoreleasepool 中,那么@autoreleasepool块结束之前能够确保对象的存在。例如:

    id __weak obj1 = obj0;
    NSLog(@“class=%@”,[obj class]);
    
    #对应的模拟源码为:
    id __weak obj1 = obj0;
    id __autoreleaseing tmp = obj1;
    NSLog(@“class = %@”, [tmp class]);
    

       第三种:id 的指针或对象的指针在没有显示指定时会被附加__autoreleasing 修饰符

    + (nullable instancetype)stringWithContentsOfURL:(NSURL *)url
                              encoding:(NSStringEncoding)enc
                              error:(NSError **)error;
    
    NSString *str = [NSString stringWithContentsOfURL:
                   encoding:
                   error:<#(NSError * _Nullable __autoreleasing * _Nullable)#>]
    

    子线程默认不会开启Runloop,那么出现Autorelease 对象如何处理?不手动处理会内存泄漏吗?

    简单阐述下,在子线程你创建了 Pool 的话,产生的 Autorelease 对象就会交给 pool 去管理。如果你没有创建 Pool ,但是产生了 Autorelease 对象,就会调用 autoreleaseNoPage 方法。在这个方法中,会自动帮你创建一个 hotpage(hotPage 可以理解为当前正在使用的 AutoreleasePoolPage,如果你还是不理解,可以先看看 Autoreleasepool 的源代码,再来看这个问题 ),并调用 page->add(obj) 将对象添加到 AutoreleasePoolPage 的栈中,也就是说你不进行手动的内存管理,也不会内存泄漏啦!StackOverFlow 的作者也说道,这个是 OS X 10.9+和 iOS 7+ 才加入的特性。

    参考:
    引用计数带来的一次讨论

    相关文章

      网友评论

          本文标题:Autorelease 对象的内存管理

          本文链接:https://www.haomeiwen.com/subject/izfeqhtx.html