请教关于 __weak 的问题 - V2EX
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

请教关于 __weak 的问题

  •  
  •   georgetso 2015-07-10 10:23:20 +08:00 3281 次点击
    这是一个创建于 3825 天前的主题,其中的信息可能已经有所发展或是发生改变。
    方法声明
    - (void)foo:(NSObject __weak *)obj {}

    方法调用
    [self foo:bar];

    bar 是一个 strong referenced object
    传入后的obj设置 __weak 关键字后,是否会变成 weak?
    第 1 条附言    2015-07-10 15:07:41 +08:00
    形参会在函数调用时入栈,对不?

    那么在下面这个方法声明中
    - (void) foo:(__strong NSObject *)bar {}

    形参 bar 是一个 NSObject 指针,并且在入栈时,对 实参 强饮用


    而在下面这个方法声明中
    - (void) foo:(__weak NSObject *)bar {}

    形参 bar 是一个 NSObject 指针,并且在入栈时,对 实参 弱饮用



    如果以上解释是正确的,那么方法声明时的引用修饰符,就是有效的吧?
    12 条回复    2015-07-16 09:52:00 +08:00
    w99wen
        1
    w99wen  
       2015-07-10 10:46:50 +08:00
    会的把。

    我想到的类似的情况:

    在代码块中使用self的时候,有是有也要用 __weak的新的局部变量weakself来替换self,这样就不会出现内存死锁的问题。你这个不是一样吗。self就是你的这个bar,bar不会被释放的。不过再你的方法内部,这个bar,也就是方法内部的obj是__weak的,里面的strong的数据能被正常释放而不会死锁。

    那个和你这个很像。
    newtonisaac
        2
    newtonisaac  
       2015-07-10 10:53:57 +08:00
    不要这样用。
    georgetso
        3
    georgetso  
    OP
       2015-07-10 10:55:29 +08:00
    vincentxue
        4
    vincentxue  
       2015-07-10 11:37:21 +08:00
    ARC 环境下在此处放一个关键字是告诉编译器如何正确处理这个引用。所以你方法调用后,bar 依然是 strong 的,但 obj 是 weak 的。因为 OC 传进来的是引用。
    noli
        5
    noli  
       2015-07-10 11:59:02 +08:00
    设置函数参数是 __weak 引用是没有作用、没有实际意义的:

    1. 假如传入参数并且运行以后,没有任何其他变量持有(retain) 这个对象,那么传进去是 __weak 是 __strong 都对生命周期没有任何影响。

    2. 假如传入参数并且运行以后,有一个或者多个其他变量 retain 了这个对象,那么决定参数的引用计数增加的,是持有者本身是 __weak 还是 __strong,跟传进去的时候是怎样没有关系
    loveuqian
        6
    loveuqian  
       2015-07-10 12:17:38 +08:00 via iPhone
    同问
    参数还能带weak的?
    声明后面为啥有大括号啊
    anerevol
        7
    anerevol  
       2015-07-10 12:21:56 +08:00
    楼上说得不错。
    再补充下,weak,strong是修饰指向对象指针的,而不是对象本身。
    kobe1941
        8
    kobe1941  
       2015-07-10 12:53:43 +08:00
    @noli 认同函数的形参是__weak 引用无意义,且其对 引用计数无影响,不过我更愿意这样子解释:

    Objective-C里对象都是用指针指向,决定对象的引用计数增加的,是另一个__strong指针指向了该对象所在的内存,那么根据的楼主的原题,形参用__weak修饰,一个__weak指针把该对象的地址传递进了函数里,相当于多了一个__weak指针指向原对象的内存地址,对象引用计数不变,之后该形参被销毁,确实是无意义。

    不过我倒是认为,默认用__strong修饰的形参,会在传递参数给函数的时候使对象的引用计数+1,之后函数调用完毕,形参因超出函数作用域而销毁,从而使原对象引用计数-1。最终形参不影响该对象的引用计数。

    只是悲剧的是,我没办法验证,给对象发送retanCount返回的值是不准确的。
    newtonisaac
        9
    newtonisaac  
       2015-07-10 13:09:41 +08:00
    @georgetso 变量声明的时候用
    georgetso
        10
    georgetso  
    OP
       2015-07-10 15:08:03 +08:00
    @loveuqian 不要在意这些细节
    110293734
        11
    110293734  
       2015-07-10 16:06:13 +08:00
    stack的时候,声明一个临时变量默认是__strong 修饰符,如果是__weak,直接变nil。
    你可以xcode 试下。看看出啥警告

    one word:不建议这么用 ,NSError *__autorelease*error 除外,因为指针的指针,已经跳出 ARC管理范围了。
    rannie
        12
    rannie  
       2015-07-16 09:52:00 +08:00
    __weak 修饰参数没有什么意义吧
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3257 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 04:48 PVG 12:48 LAX 20:48 JFK 23:48
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86