为什么在强引用消失后我的弱引用没有被清除? [英] Why isn’t my weak reference cleared right after the strong ones are gone?

查看:137
本文介绍了为什么在强引用消失后我的弱引用没有被清除?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有点固执,但是我想很好地理解弱引用和强引用,所以这就是为什么我再次问你.

I am a little bit stubborn, but I want to understand weak and strong references well, so that's why I'm asking you once again.

请考虑以下问题:

__weak NSString* mySecondPointer = myText;   
NSLog(@"myText: %@", myText);

结果为myText: (null),这非常明显-分配后刚将弱引用设置为null,这是因为没有对指向对象的强引用.

The result is myText: (null) and it is pretty obvious - weak reference is set to null just after assignment, cause there is no strong reference to the pointed object.

但是在这种情况下:

__strong NSString* strongPtr = [[NSString alloc] initWithFormat:@"mYTeSTteXt %d"]; 
// weak pointer points to the same object as strongPtr
__weak NSString* weakPtr = strongPtr;
if(strongPtr == weakPtr) 
     NSLog(@"They are pointing to the same obj");        
NSLog(@"StrongPtr: %@", strongPtr);
NSLog(@"weakPtr: %@", weakPtr);

NSLog(@"Setting myText to different obj or nil");

// after line below, there is no strong referecene to the created object:
strongPtr = [[NSString alloc] initWithString:@"abc"];  // or myText=nil;

if(strongPtr == weakPtr) 
     NSLog(@"Are the same");
else
     NSLog(@"Are NOT the same");
NSLog(@"StrongPtr: %@", strongPtr);
// Why weak pointer does not point to nul
NSLog(@"weakPtr: %@", weakPtr);

输出:

2013-03-07 09:20:24.141 XMLTest[20048:207] They are pointing to the same obj
2013-03-07 09:20:24.142 XMLTest[20048:207] StrongPtr: mYTeSTteXt 3
2013-03-07 09:20:24.142 XMLTest[20048:207] weakPtr: mYTeSTteXt 3
2013-03-07 09:20:24.143 XMLTest[20048:207] Setting myText to different obj or nil
2013-03-07 09:20:24.143 XMLTest[20048:207] Are NOT the same
2013-03-07 09:20:24.144 XMLTest[20048:207] StrongPtr: abc
2013-03-07 09:20:24.144 XMLTest[20048:207] weakPtr: mYTeSTteXt 3   // <== ??

我的问题:

为什么在strongPtr = [[NSString alloc] initWithString:@"abc"];弱指针值之后没有更改为nil(为什么在开始时创建的对象仍然存在于内存中,尽管它没有任何强引用?或者也许有?)

Why after strongPtr = [[NSString alloc] initWithString:@"abc"]; weak pointer value is not changed to nil (why the object created at the beginning still exists in memory, despite it does not have any strong refs? -- or maybe it has?)

我尝试过一个:(但是我想添加评论不是很好).我已经包含了在@autorealesepool中创建strongPtr的代码.我不确定这是否是正确的解决方案,但是可以正常工作...

I have tried that one: (but it is not good for adding a comment I suppose). I have included the code where I am creating a strongPtr in @autorealesepool. I not sure if it is correct solution but it work...

 __strong NSString* strongPtr;
    __weak NSString* weakPtr;
    @autoreleasepool {


        strongPtr = [[NSString alloc] initWithFormat:@"mYTeSTteXt %d", 3];

        // weak pointer point to object create above (there is still strong ref to this obj)
        weakPtr = strongPtr;
        if(strongPtr == weakPtr) NSLog(@"They are pointing to the same obj");        

        NSLog(@"StrongPtr: %@", strongPtr);
        NSLog(@"weakPtr: %@", weakPtr);

        NSLog(@"Setting myText to different obj or nil");   

    // after line below, there is no strong referecene to the created object:
     strongPtr = [[NSString alloc] initWithString:@"abc"];  


    }

    if(strongPtr == weakPtr) 
        NSLog(@"Are the same");
    else
        NSLog(@"Are NOT the same");
    NSLog(@"StrongPtr: %@", strongPtr);
    // Why weak pointer does not point to nul
    NSLog(@"weakPtr: %@", weakPtr);

输出:

2013-03-07 09:58:14.601 XMLTest[20237:207] They are pointing to the same obj
2013-03-07 09:58:14.605 XMLTest[20237:207] StrongPtr: mYTeSTteXt 3
2013-03-07 09:58:14.605 XMLTest[20237:207] weakPtr: mYTeSTteXt 3
2013-03-07 09:58:14.606 XMLTest[20237:207] Setting myText to different obj or nil
2013-03-07 09:58:14.607 XMLTest[20237:207] Are NOT the same
2013-03-07 09:58:14.607 XMLTest[20237:207] StrongPtr: abc
2013-03-07 09:58:14.608 XMLTest[20237:207] weakPtr: (null)

推荐答案

从汇编代码中可以看出,访问weakPtr会生成objc_loadWeak调用.

From the assembly code it can be seen that accessing weakPtr generates a objc_loadWeak call.

根据 Clang文档保留并自动释放对象,等效于

According to the Clang documentation, objc_loadWeak retains and autoreleases the object and is equivalent to

id objc_loadWeak(id *object) {
  return objc_autorelease(objc_loadWeakRetained(object));
}

(希望如此)解释两者的原因

This (hopefully) explains why both

if(strongPtr == weakPtr) ...

NSLog(@"weakPtr: %@", weakPtr);

创建其他自动发布的引用.

create additional autoreleased references.

这不是一个特殊的NSString问题,我可以使用自定义(普通)类重现相同的行为.

This is not a special NSString problem, I could reproduce the same behaviour with a custom (plain) class.

这篇关于为什么在强引用消失后我的弱引用没有被清除?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆