好吧,先说最终结论,没有最终结论,我也不知道用啥。
这两个都是三目运算符,在我们给属性或者参数设置非空数据时十分常用,然后,我就十分好奇到底用哪种写法更好(其实我喜欢第二种,更简洁,跟swift ?? 更像,也好理解),
但是吧,感觉不行啊,得有证据,所以简单编写了一个测试代码,并用objdump把中间文件给打印了一下,
代码简单的不要不要的:
-(void)functionOne {
NSString * a = @"";
NSString * b = a ? a : @"";
}
-(void)functionTwo {
NSString * a = @"";
NSString * b = a ?: @"";
}
中间文件(.o)的位置在/Users/UName/Library/Developer/Xcode/DerivedData/$PROJECTNAME-RandomString/Build/Intermediates.noindex/$PROJECTNAME.build/Debug-iphonesimulator/$PROJECTNAME.build/Objects-normal/x86_64
里面的$PROJECTNAME的位置自己替换
中间文件如下图.0文件
然后再终端敲kyang@Kyang-3 x86_64 % objdump -S -g DumpTest.o
就把编译后的文件打印出来了。
这边就不贴代码了,直接贴个图
简单分析一下就看到 ?:的方式比 ? : 的方式要多了两行指令,说明它并不能直接理解 ?: 这种形式,而是对它做了一定的转换,比直接对比,多了两条指令。
是不是就说明 ?:比 ? :要慢????
不过吧,现在cpu都这么屌,这两条肯定不算事儿了,具体用哪个大家还是看个人喜好吧。PS:怎么办,想建议别人换成?:😶😶😶,别急!!!
然后我们换个稍微复杂点的例子,真的是稍微复杂点
-(void)functionOne {
NSString * b = [self randomString] ? [self randomString] : @"";
}
-(void)functionTwo {
NSString * b = [self randomString] ?: @"";
}
-(NSString * __nullable)randomString {
if (arc4random() % 2) {return @"a";}
return nil;
}
然后重复上面的操作,得到两个方法的汇编指令的对比:
一屏装不下啊,拖了拖
可以看到,指令不止多了一点半点,区别还是很大的,这次,反而是 ?: y以大优势反超。
其实也好理解:
NSString * b = [self randomString] ? [self randomString] : @"";
/*
1. 执行[self randomString]
2. 判断返回值是不是为空
3. 如果不为空那么
4. 继续执行[self randomString]
5. 返回值赋值给b
*/
NSString * b = [self randomString] ?: @"";
/*
1. 执行[self randomString]
2. 判断返回值是不是为空
3. 如果不为空那么 下一步
4. 返回值赋值给b
*/
第二种方式少执行了一个方法,这里仅仅是一个if else,但如果是是一个其他的方法,比如富文本之类的,差距只会是更大!!
可以给一个不严谨的结论了:
- 如果是简单判断的话,用
a?:b
,差距很小,可以忽略,但是好看😄。 - 如果是条件复杂一点的判断,比如条件是一个方法,用
a?:b
,能省去一个方法的执行,越复杂越省,关键好看啊😄😄
网友评论