我最近一直在学习ruby,基本上爱上了|| = feature,因为它会让Objective C中的懒惰getter变得更容易。
目前我写的是吸气剂,如:
- (NSArray *)myArray {
if (!_myArray) {
_myArray = [NSArray array];
}
return _myArray
}
除非我遗漏了|| =的东西,否则我可以用Ruby编写以前的代码:
- (NSArray *)myArray {
return _myArray ||= [NSArray array];
}
这显然更清洁了。 Objective-C语言/运行时中是否有任何可以实现此功能的内容?
此外,以下是getter的单行三元组,我不确定它是否与上面发布的尝试和真实方法一样有效(第一个片段)。如果有人做错了,有人可以告诉我:
- (NSArray *)myArray {
return _myArray = _myArray ? _myArray : [NSArray array];
}
答案 0 :(得分:11)
最后一个片段与您发布的第一个片段效果相同。
作为改进,虽然Objective-C中没有像||=
这样的运算符,但您可以省略三元if运算符的第二个参数并执行
return _myArray = _myArray ?: [NSArray array];
完全等同于
return _myArray = _myArray ? _myArray : [NSArray array];
奖励:如果你想节省更多的击键,你可以做
- (NSArray *)myArray {
return _myArray = _myArray ?: @[];
}
作为旁注,跳过中间操作数也可以带来一些好处。
例如在这种情况下
id x = [self someMethod] ? [self someMethod] : [self anotherMethod];
如果someMethod
评估为true
,则会调用两次,而执行
id x = [self someMethod] ?: [self anotherMethod];
它只会被调用一次。
答案 1 :(得分:3)
除非你想要hack on Clang,否则没有字面上的等价物。 ||
逻辑运算符在短路时不会评估其操作数。使用三元条件的宏将使您接近:
#define NON_NIL(o, p) ((o) ? (o) : (p))
- (NSMutableArray *)myArray
{
return _myArray = NON_NIL(_myArray, [NSMutableArray array]);
}
因为C类中的赋值行为类似于表达式并且计算为指定的值。
你实际上也可以创建一个OR_ASSIGN()
宏,但我会将其留作完全疯狂读者的练习。
也许同样疯狂的是一个功能:
id lazySet(id *obj; id(^valBlock)(void))
{
if( !(*obj) ){
*obj = valBlock();
}
return *obj;
}
- (NSMutableArray *)myArray
{
return lazySet(&_myArray, ^{return [NSMutableArray array]});
}
但这太荒谬了。