强引用(目标-C)

时间:2013-04-29 02:54:34

标签: objective-c weak-references strong-references

我正在尝试更好地理解强引用,但在下面列出的特定示例的上下文中。

让我们说我有一个名为gPrefs的全局变量。它是Preference Class类型,是我制作的自定义类。

我在其界面中声明了以下内容......

@property (strong) NSURL            *masterFolder;

这是指向NSURL对象的指针。我已经给它(强)参考意思它会坚持下去而不释放它的记忆。

现在假设我在其他地方有一个实例函数,如下所示。

- (IBAction)masterDataSelectButtonAction:(id)sender
{
    NSOpenPanel *openPanel = [NSOpenPanel openPanel];//creates an open panel.
    [openPanel setCanChooseDirectories:YES];
    [openPanel setCanChooseFiles:NO];

    NSInteger panelResult = [openPanel runModal];

    if(panelResult == NSFileHandlingPanelCancelButton){
        NSLog(@"masterDataSelectButtonAction -> Cancel Button Pressed");
        return;
    }

    if(panelResult == NSFileHandlingPanelOKButton){
        NSLog(@"masterDataSelectButtonAction-> Ok Button Pressed");
        NSURL *theUrl = [openPanel URL];
        gPrefs.masterFolder = theUrl; //Setting (strong ref) point to local.
        [_masterDataLabel setStringValue:[gPrefs.masterFolder absoluteString]];
    }
}

如果此人按下面板的OK按钮,我将创建一个名为theUrl的本地指针实例变量。然后我将全局变量masterFolder指针设置为本地实例变量指针。

如果我理解正确ARC应该在函数结束时释放对象,当它认为它不再被使用时。

因此,应该在函数结束时释放url。

但是,如果我理解(强)引用,编译器可能足够智能,因为我将全局首选项指针更改为不同的指针,它将使其他指针在内存中保持活动(或保留它)。 / p>

如果我没有将masterFolder指针声明为(强),那么在函数结束后masterFolder指针是否为nil?

我的实验表明,保持它(强)似乎保留了localInstance指针的值,尽管到达了本地实例函数的末尾。

我的问题是为什么?即使masterFolder是一个强引用,如果我将它分配给localInstance指针并且在Instance函数结束时删除了该指针,为什么masterFolder的值在我从其他地方的实例函数之外再次读取时不会出现NIL

我对(强)参考的理解有点(弱)。没有双关语。

2 个答案:

答案 0 :(得分:3)

NSURL *theUrl = [openPanel URL];

theURL位于函数范围内(或if块内,但在此示例中并没有区别)。 theURL指向的对象位于堆上。在函数结束时,当theURL超出范围时,堆上对象的引用计数将减少1(因为theURL是对象的强引用。如果在指向引用计数变为0,对象被释放。在你的情况下,至少有一个对该对象的强引用(在你的全局单例中),所以对象保持活动状态。堆上的对象不是本地的,因此,记忆不会超出范围。

如果全局单例具有弱引用,则一旦对象的引用计数达到0并且对象被释放,它将自动设置为nil

答案 1 :(得分:2)

如此强大真的只是保留。当您拨打gPrefs.masterFolder = theUrl;时,您正在将指针masterFolder设置为与theUrl相同,并在masterFolder上调用保留。因此,在创建theUrl时,它的保留计数为1;设置为masterFolder的强属性后,theUrl保留了对其的调用,将其保留计数增加到2.这就是为什么它在实例方法完成后不会消失的原因自动释放theUrl,theUrl仍然保留计数为1,因为它被设置为强属性。

现在,如果您将该属性设置为弱,那么masterFolder nil的行为theUrlautorelease的行为将被masterFolder正确销毁。 weak只是将theUrl设置为与{{1}}相同,但不会在其上调用retain。