ma1*_*w28 41 cocoa cocoa-touch memory-management objective-c automatic-ref-counting
使用alloc或autorelease初始化器更好(更快,更高效).例如:
- (NSString *)hello:(NSString *)name {
return [[NSString alloc] initWithFormat:@"Hello, %@", name];
}
Run Code Online (Sandbox Code Playgroud)
要么
- (NSString *)hello:(NSString *)name {
return [NSString stringWithFormat:@"Hello, %@", name];
// return [@"Hello, " stringByAppendingString:name]; // even simpler
}
Run Code Online (Sandbox Code Playgroud)
我知道在大多数情况下,这里的表现无关紧要.但是,我仍然希望养成以更好的方式做这件事的习惯.
如果他们做同样的事情,那么我更喜欢后一种选择,因为它的输入更短,更具可读性.
在Xcode 4.2,有没有办法,看看有什么ARC编译成,也就是说,它把retain,release,autorelease,等?切换到ARC时,此功能非常有用.我知道你不应该考虑这些东西,但它能帮助我弄清楚这些问题的答案.
Stu*_*nie 37
差异很微妙,但您应该选择autorelease版本.首先,您的代码更具可读性.其次,在检查优化的装配输出时,autorelease版本稍微更优化.
该autorelease版本中,
- (NSString *)hello:(NSString *)name {
return [NSString stringWithFormat:@"Hello, %@", name];
}
Run Code Online (Sandbox Code Playgroud)
翻译成
"-[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}
Run Code Online (Sandbox Code Playgroud)
而[[alloc] init]版本如下所示:
"-[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
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,它会更长一点,因为它正在调用alloc和initWithFormat:方法.特别有趣的是ARC在这里生成次优代码,因为它保留了name字符串(通过调用_objc_retain注释),并在调用之后释放initWithFormat:.
如果我们添加__unsafe_unretained所有权限定符,如下例所示,代码将以最佳方式呈现. __unsafe_unretained指示编译器使用原语(复制指针)赋值语义.
- (NSString *)hello:(__unsafe_unretained NSString *)name {
return [[NSString alloc] initWithFormat:@"Hello, %@", name];
}
Run Code Online (Sandbox Code Playgroud)
如下:
"-[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
Run Code Online (Sandbox Code Playgroud)
Tam*_*ese 10
[NSString stringWithFormat:]是更少的代码.但请注意,对象可能最终会出现在自动释放池中.即使使用ARC和-Os编译器优化,目前也会发生这种情况.
目前,[[NSString alloc] initWithFormat:]iOS(使用iOS 5.1.1和Xcode 4.3.3测试)和OS X(使用OS X 10.7.4和Xcode 4.3.3测试)的性能更佳.我修改了@Pascal的示例代码以包含自动释放池的排放时间并得到以下结果:
[[NSString alloc] initWithFormat:]在iPhone 4S上快约14%,在OS X上快约8%在循环周围有一个@autoreleasepool会释放循环中的所有对象,从而占用大量内存.
![在iOS 5.1上显示[NSString stringWithFormat:]而不是[[NSString alloc] initWithFormat:]的内存峰值的工具](https://i.stack.imgur.com/Z43Cg.png)
| 归档时间: |
|
| 查看次数: |
7323 次 |
| 最近记录: |