为什么我的弱引用清除强者都消失后,对不对?(Why isn’t my weak reference

2019-07-21 03:32发布

我有点固执,但我想知道好强和弱引用,所以这就是为什么我在问你一次。

试想一下:

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

其结果是myText: (null) ,这是非常明显的-弱引用仅有转让后,空,原因是没有强有力的参考尖锐的物体。

但是,在这种情况下:

__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"]; 弱指针的值没有改变为零(为什么一开始仍然存在于内存中,尽管它没有任何强烈的裁判创建的对象 - ?也许它有)


我已尝试之一:(但不利于添加注释,我想)。 我已经包括在那里,我创造了一个@autorealesepool的strongPtr代码。 我不知道这是否是正确的解决方案,但它的工作...

 __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)

Answer 1:

从汇编代码可以看出,访问weakPtr产生objc_loadWeak呼叫。

根据锵文档 , objc_loadWeak保持和自动释放物体,相当于

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

这(希望)解释了为什么这两个

if(strongPtr == weakPtr) ...

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

创建额外的自动释放引用。

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



Answer 2:

首先,不要与弱引用或其它存储管理性能试验NSString ,有一个在该类太多神奇。 这并不是说弱引用不会与工作NSString ,只是行为稍有棘手比你所期望的,并容易导致不正确的结论。 看到这些以前的问题:

  • 如预期弱attritube不起作用
  • 为什么弱的NSString属性不是在iOS发布?
  • NSString的保留计数

当你与一个自动释放池包装你的代码示例和事后记录弱字符串的指针,它是nil确实如此。 它甚至可能是你会得到比其他类的类似行为的情况下NSString -你根本不保证该弱引用将在适当的时机,清除你失去了最后的强引用的对象。 或者,也许你是,但很难说什么时候,因为在游戏中自动释放池的最后一个强引用消失,正如这个例子暗示(和马丁的回答很好地解释)。



Answer 3:

当你做

strongPtr = [[NSString的页头] initWithString:@ “ABC”]

你strongPtr指向新分配的对象,并且因为以前的对象时,它是指向太没有得到解除了分配,弱指针依然指向一个有效的地址。

顺便说一句。 你可以打印内存地址了与对象

的NSLog(@ “%@”,[的NSString stringWithFormat:@ “%P”,theObject])



Answer 4:

不知道OP的问题和/或在这里接受的答案仍然是有效的,至少不会像我和iOS9 / Xcode7看到的结果。

下面是OP的代码(稍微清理)版本...

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{
    @autoreleasepool
    {
        NSString* __strong strongPtr = [[NSString alloc] initWithFormat:@"Life, Universe, Everything: %d", 42];
        NSString* __weak   weakPtr   = strongPtr;

        NSLog(strongPtr == weakPtr ? @"Same" : @"Different");
        NSLog(@"  StrongPtr: %@", strongPtr);
        NSLog(@"  weakPtr:   %@", weakPtr);

        NSLog(@"Changing strongPtr to something else...");
        // After this is set, there is no strong reference to the created object
        strongPtr = [[NSString alloc] initWithFormat:@"Drink: %@", @"Pan-galactic Gargle Blaster!"];

        NSLog(strongPtr == weakPtr ? @"Same" : @"Different");
        NSLog(@"  StrongPtr: %@", strongPtr);
        NSLog(@"  weakPtr:   %@", weakPtr);
    }

    return 0;
}

而这里的(截)输出...

Same
  StrongPtr: Life, Universe, Everything: 42
  weakPtr:   Life, Universe, Everything: 42

Changing strongPtr to something else...

Different
  StrongPtr: Drink: Pan-galactic Gargle Blaster!
  weakPtr:   (null)

Program ended with exit code: 0

这里访问的条件语句的弱引用(按照公认的答案的解释)不保留在输出自动释放引用作为你周围可以通过(空)见。

...还是我不小心改变OP的问题的地步,我躲到什么他看见了什么? 或者,也许它现在是因为ARC是默认?



文章来源: Why isn’t my weak reference cleared right after the strong ones are gone?