在实例化之前检查指针是否为nil

时间:2014-08-26 16:54:56

标签: objective-c

我是Objective-C的新手,当我看到if检查属性的getter时,我感到非常困惑:

- (XXX)name {
    if (!_name) _name = [[XXX alloc] init];
    return _name;
}

为什么在实例化时必须检查指针是否为nil?并非所有对象都以0(零)开头?为什么你不能让指针指向左边新实例化的对象?

3 个答案:

答案 0 :(得分:1)

当您考虑多次调用name时,您可以看到这一点。对特定实例的第一次调用将分配_name。在随后的调用_name中,nil不会dispatch_once,因此将返回先前分配的项目。

这是一种懒惰的初始化模式。在单线程环境中,以及在线程之间不共享具有此方法的对象的环境中,此实现很好。

在并发环境中,您应该使用此模式的线程安全版本,该版本使用锁定或{{1}}方法。

答案 1 :(得分:0)

  

为什么在实例化时必须检查指针是否为nil?

第二次调用getter方法时,它已经实例化了。当您只想实例化一次属性时,将使用此模式。如果它是nil你还没有完成它。如果它是非nil,则只返回值。

  

是不是所有对象都以0(零)开始?

是的。如果它是nil,那意味着你需要实例化它。所以继续这样做,从那时起返回那个实例。

  

为什么不能让指针指向左边新实例化的对象?

咦?我不知道你在这里问什么。

答案 2 :(得分:0)

这是Objective-C中非常常见的迷你模式。例如,您可以在自定义属性getter中看到它。我们的想法是创建一个对象,但前提是你之前没有创建过一个对象(如果有的话,只需返回它)。正如@Nicholas Hart在评论中所说,这也有助于实现延迟初始化(如果引用它就会创建一个对象。

E.g:

- (MyType *)myProperty
{
     if(!_myProperty)
    {
         _myProperty = [[MyType alloc] init];
    }
    return _myProperty;
}

// somewhere else, you want to use the property:
[self.myProperty doSomething];

在对doSomething的调用中,将调用getter方法myProperty,并初始化_myProperty ivar(位于myProperty属性后面),如果必要的。