我是Objective-C的新手,当我看到if
检查属性的getter时,我感到非常困惑:
- (XXX)name {
if (!_name) _name = [[XXX alloc] init];
return _name;
}
为什么在实例化时必须检查指针是否为nil?并非所有对象都以0(零)开头?为什么你不能让指针指向左边新实例化的对象?
答案 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
属性后面),如果必要的。