使用 ARC,哪个更好:alloc 或 autorelease 初始化程序? [英] With ARC, what's better: alloc or autorelease initializers?
问题描述
使用 alloc
或 autorelease
初始值设定项是否更好(更快、更有效).例如:
Is it better (faster & more efficient) to use alloc
or autorelease
initializers. E.g.:
- (NSString *)hello:(NSString *)name {
return [[NSString alloc] initWithFormat:@"Hello, %@", name];
}
或
- (NSString *)hello:(NSString *)name {
return [NSString stringWithFormat:@"Hello, %@", name];
// return [@"Hello, " stringByAppendingString:name]; // even simpler
}
我知道在大多数情况下,这里的性能并不重要.但是,我还是想养成以更好的方式去做的习惯.
I know that in most cases, performance here shouldn't matter. But, I'd still like to get in the habit of doing it the better way.
如果他们做的完全一样,那么我更喜欢后一种选择,因为它打字更短,可读性更强.
If they do exactly the same thing, then I prefer the latter option because it's shorter to type and more readable.
在 Xcode 4.2 中,有没有办法查看 ARC 编译成什么,即它把 retain
、release
、autorelease
放在哪里,等等?此功能在切换到 ARC 时非常有用.我知道你不应该考虑这些东西,但它会帮助我找出这些问题的答案.
In Xcode 4.2, is there a way to see what ARC compiles to, i.e., where it puts retain
, release
, autorelease
, etc? This feature would be very useful while switching over to ARC. I know you shouldn't have to think about this stuff, but it'd help me figure out the answer to questions like these.
推荐答案
差异很小,但您应该选择 autorelease
版本.首先,您的代码更具可读性.其次,在检查优化后的汇编输出时,autorelease
版本稍微优化一些.
The difference is subtle, but you should opt for the autorelease
versions. Firstly, your code is much more readable. Secondly, on inspection of the optimized assembly output, the autorelease
version is slightly more optimal.
autorelease
版本,
- (NSString *)hello:(NSString *)name {
return [NSString stringWithFormat:@"Hello, %@", name];
}
翻译成
"-[SGCAppDelegate hello:]":
push {r7, lr}
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_-(LPC0_0+4))
mov r3, r2
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_-(LPC0_0+4))
movw r0, :lower16:(L_OBJC_CLASSLIST_REFERENCES_$_-(LPC0_1+4))
movt r0, :upper16:(L_OBJC_CLASSLIST_REFERENCES_$_-(LPC0_1+4))
add r1, pc
add r0, pc
mov r7, sp
ldr r1, [r1]
ldr r0, [r0]
movw r2, :lower16:(L__unnamed_cfstring_-(LPC0_2+4))
movt r2, :upper16:(L__unnamed_cfstring_-(LPC0_2+4))
add r2, pc
blx _objc_msgSend ; stringWithFormat:
pop {r7, pc}
而 [[alloc] init] 版本如下所示:
Whereas the [[alloc] init] version looks like the following:
"-[SGCAppDelegate hello:]":
push {r4, r5, r6, r7, lr}
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_2-(LPC1_0+4))
add r7, sp, #12
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_2-(LPC1_0+4))
movw r0, :lower16:(L_OBJC_CLASSLIST_REFERENCES_$_-(LPC1_1+4))
movt r0, :upper16:(L_OBJC_CLASSLIST_REFERENCES_$_-(LPC1_1+4))
add r1, pc
add r0, pc
ldr r5, [r1]
ldr r6, [r0]
mov r0, r2
blx _objc_retain ; ARC retains the name string temporarily
mov r1, r5
mov r4, r0
mov r0, r6
blx _objc_msgSend ; call to alloc
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_4-(LPC1_2+4))
mov r3, r4
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_4-(LPC1_2+4))
add r1, pc
ldr r1, [r1]
movw r2, :lower16:(L__unnamed_cfstring_-(LPC1_3+4))
movt r2, :upper16:(L__unnamed_cfstring_-(LPC1_3+4))
add r2, pc
blx _objc_msgSend ; call to initWithFormat:
mov r5, r0
mov r0, r4
blx _objc_release ; ARC releases the name string
mov r0, r5
pop.w {r4, r5, r6, r7, lr}
b.w _objc_autorelease
正如预期的那样,它有点长,因为它调用了 alloc
和 initWithFormat:
方法.特别有趣的是 ARC 在这里生成了次优代码,因为它保留了 name
字符串(通过调用 _objc_retain 来说明),然后在调用 initWithFormat:
后释放.
As expected, it is a little longer, because it is calling the alloc
and initWithFormat:
methods. What is particularly interesting is ARC is generating sub-optimal code here, as it retains the name
string (noted by call to _objc_retain) and later released after the call to initWithFormat:
.
如果我们添加 __unsafe_unretained
所有权限定符,如下例所示,代码将得到最佳呈现.__unsafe_unretained
指示编译器使用原语(复制指针)赋值语义.
If we add the __unsafe_unretained
ownership qualifier, as in the following example, the code is rendered optimally. __unsafe_unretained
indicates to the compiler to use primitive (copy pointer) assignment semantics.
- (NSString *)hello:(__unsafe_unretained NSString *)name {
return [[NSString alloc] initWithFormat:@"Hello, %@", name];
}
如下:
"-[SGCAppDelegate hello:]":
push {r4, r7, lr}
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_2-(LPC1_0+4))
add r7, sp, #4
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_2-(LPC1_0+4))
movw r0, :lower16:(L_OBJC_CLASSLIST_REFERENCES_$_-(LPC1_1+4))
movt r0, :upper16:(L_OBJC_CLASSLIST_REFERENCES_$_-(LPC1_1+4))
add r1, pc
add r0, pc
mov r4, r2
ldr r1, [r1]
ldr r0, [r0]
blx _objc_msgSend
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_4-(LPC1_2+4))
mov r3, r4
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_4-(LPC1_2+4))
add r1, pc
ldr r1, [r1]
movw r2, :lower16:(L__unnamed_cfstring_-(LPC1_3+4))
movt r2, :upper16:(L__unnamed_cfstring_-(LPC1_3+4))
add r2, pc
blx _objc_msgSend
.loc 1 31 1
pop.w {r4, r7, lr}
b.w _objc_autorelease
这篇关于使用 ARC,哪个更好:alloc 或 autorelease 初始化程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!