V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iOS 开发实用技术导航
NSHipster 中文版
http://nshipster.cn/
cocos2d 开源 2D 游戏引擎
http://www.cocos2d-iphone.org/
CocoaPods
http://cocoapods.org/
Google Analytics for Mobile 统计解决方案
http://code.google.com/mobile/analytics/
WWDC
https://developer.apple.com/wwdc/
Design Guides and Resources
https://developer.apple.com/design/
Transcripts of WWDC sessions
http://asciiwwdc.com
Cocoa with Love
http://cocoawithlove.com/
Cocoa Dev Central
http://cocoadevcentral.com/
NSHipster
http://nshipster.com/
Style Guides
Google Objective-C Style Guide
NYTimes Objective-C Style Guide
Useful Tools and Services
Charles Web Debugging Proxy
Smore
georgetso
V2EX  ›  iDev

关于 ARC,有疑问请教

  •  
  •   georgetso · 2015-02-06 17:42:43 +08:00 · 2161 次点击
    这是一个创建于 3577 天前的主题,其中的信息可能已经有所发展或是发生改变。
    问题1
    - (void)aMethodInAClass:(NSData *)data {
    NSString *s = [[NSString alloc] initWithData:data encoding:4];
    ......
    s = nil;
    }

    请问以上方法中, s = nil 是否是必须的?

    问题2
    @interface Person {
    NSString * __strong name;
    }
    @property NSString *name;
    @end
    在这样的类定义中,是否需要在 dealloc 方法中 nil out name?
    如果需要,那么 self.name = nil 和 name = nil 的区别是?
    7 条回复    2015-02-12 12:48:44 +08:00
    66450146
        1
    66450146  
       2015-02-06 18:03:30 +08:00
    1. 不需要
    2. 不需要

    ARC 就是这么任性
    Madimo
        2
    Madimo  
       2015-02-06 18:05:05 +08:00
    1.不是
    2.不需要
    在开启 ARC 的情况下,只要避免循环引用,所有的变量都会被正确释放。
    noli
        3
    noli  
       2015-02-06 18:20:03 +08:00
    要理解ARC,了解一个变量的作用域是很有必要的。

    1. 变量 s 的作用域位是 aMethodInAClass 方法“被调用”的期间,执行完方法后方法就退栈了,所以s也会被回收,这种情况是ARC可以在编译期就知道的,所以可以正确插入回收代码。

    2. 成员 name 的作用域是 与具体的 Person 对象绑定的。

    就是说,只要 Person对象存在,name 就存在,只要Person 对象退出作用域或者说生命周期结束(就是 dealloc 之后),name 也会结束。

    没有形成循环引用的前提下,因为 objc 对对象的引用都可以追朔到栈上,所以Person 的生命周期可能的结束点可以肯定,必然不晚于某个函数return 时,也就是跟 s 的情形一样,是可以由编译器操纵引用计数的。所以,对于这种不可能形成循环引用的对象,在 dealloc 里面写不写 nil out 是没有区别的。

    但假如 Person 里面有一个 MyFacebook,MyFacebook 里面会引用Person 对象,那么这个时候就有可能形成循环引用。就应该根据条件 在 dealloc 之前(而不是在 dealloc 里面) nil out MyFacebook 类型的变量,避免循环引用。
    tane05
        4
    tane05  
       2015-02-06 18:59:06 +08:00
    1, 2楼言简意赅 ps问题2还有个知识点实例变量和属性的区别
    huoshanhui
        5
    huoshanhui  
       2015-02-06 19:19:52 +08:00
    @tane05 实例变量就是实例变量。属性会 synthesize 一个 _variable。
    kobe1941
        6
    kobe1941  
       2015-02-08 18:05:29 +08:00
    1.不是。因为ARC的本质是编译器帮你管理内存,编译器在编译的时候会自动在合适的地方插入retain release 或者autorelease,所以大多数东西的内存开发者不需要理会,但是定时器NSTimer和通知还有CF开头的一些东西需要自己管理。
    2.不需要。你这么写,该类会有两个成员变量,name与_name,用self.name调用的是_name。建议所有成员变量,如果可以,尽量都写成属性。

    另外,字符串类的属性,一般用nonatomic和copy属性修饰,养成好习惯。
    canautumn
        7
    canautumn  
       2015-02-12 12:48:44 +08:00
    我也来补充一个,在block里引用实例变量有隐性的self retain,容易造成隐藏的循环引用,所以要用一个指向自身的弱引用在block里引用实例变量,但是如果是concurrency的话坑就来了,这个弱引用可能在block执行一半的时候突然变成了nil,就crash了。这就需要在block里边复制一份强引用。不过属性没有后者的问题,因为给nil发消息不会crash……
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2565 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 05:01 · PVG 13:01 · LAX 21:01 · JFK 00:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.