@autorelease Pool and Loops(for,while,do)语法

Mec*_*cki 4 objective-c autorelease

clang 允许以下循环语法:

for (...) @autorelease { ... }

while (...) @autorelease { ... }

do @autorelease { ... } while (...);
Run Code Online (Sandbox Code Playgroud)

到目前为止,我还没有找到关于该语法的任何文档(Apple在其指南中没有使用这种语法,至少在引入@autorelease构造的指南中没有),但是假设上面的三个语句等同于以下三个陈述:

for (...) { @autorelease { ... } }

while (...) { @autorelease { ... } }

do { @autorelease { ... } } while (...);
Run Code Online (Sandbox Code Playgroud)

因为这是我所期望的(按标准C语法规则),但我不完全确定是否真的如此.它也可能是一些"特殊语法",其中自动释放池不会针对每次循环迭代进行更新.

Ste*_*ord 8

当您考虑任何条件语句都可以省略该{ ... }块时,第一个语法示例的工作原理很明显,导致只执行以下语句.

例如:

if (something == YES)
    NSLog(@"Something is yes");
Run Code Online (Sandbox Code Playgroud)

相当于

if (something == YES)
{
    NSLog(@"Something is yes");
}
Run Code Online (Sandbox Code Playgroud)

@autoreleasepool { ... }块只是条件后的下一个语句.

我个人使用第二种语法,因为它在进行更改时不易出错,我觉得它更容易阅读.想象一下,当您在条件和@autoreleasepool { ... }块之间添加语句时,结果与原始语句有很大不同.看到这个天真的例子......

int i = 1;
while (i <= 10)
    @autoreleasepool
    {
        NSLog(@"Iteration %d", i);
        ++i;
    }
Run Code Online (Sandbox Code Playgroud)

将"Iteration 1"输出到"Iteration 10".然而:

int i = 1;
int total = 0;
while (i <= 10)
    total += i;
    @autoreleasepool
    {
        NSLog(@"Iteration %d", i);
        ++i;
    }
Run Code Online (Sandbox Code Playgroud)

实际上会导致无限循环,因为++i语句永远不会达到,因为它在语法上等同于:

int i = 1;
int total = 0;
while (i <= 10)
{
    total += i;
}

@autoreleasepool
{
    NSLog(@"Iteration %d", i);
    ++i;
}
Run Code Online (Sandbox Code Playgroud)

  • 好吧,我知道@autorelease只是下一个声明,但我不确定它是否符合*声明*.由于这是Apple的发明而不是任何官方标准的一部分,它也可能只是一个编译器"提示"(如某些`__attribute__`语句),并且那些根本不符合*true语句*(不在语言陈述的含义). (3认同)

Par*_*fna 7

两种语法都相同

-(void)aFunc
{
    int i=0;
    for(;i<5;)
        @autoreleasepool {
            ++i;
        }
}
-(void)bFunc
{
    int i=0;
    for(;i<5;)
    {
        @autoreleasepool {
            ++i;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

汇编代码

 "-[AppDelegate aFunc]":                 ## @"\01-[AppDelegate aFunc]"
    .cfi_startproc
Lfunc_begin0:
    .loc    1 12 0                  ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:12:0
## BB#0:
    pushq   %rbp
Ltmp2:
    .cfi_def_cfa_offset 16
Ltmp3:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp4:
    .cfi_def_cfa_register %rbp
    subq    $32, %rsp
    movq    %rdi, -8(%rbp)
    movq    %rsi, -16(%rbp)
    .loc    1 14 12 prologue_end    ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:14:12
Ltmp5:
    movl    $0, -20(%rbp)
LBB0_1:                                 ## =>This Inner Loop Header: Depth=1
    .loc    1 15 5                  ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:15:5
Ltmp6:
    cmpl    $5, -20(%rbp)
    jge LBB0_3
## BB#2:                                ##   in Loop: Header=BB0_1 Depth=1
    .loc    1 16 26                 ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:16:26
Ltmp7:
    callq   _objc_autoreleasePoolPush
    .loc    1 17 13                 ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:17:13
    movl    -20(%rbp), %ecx
    addl    $1, %ecx
    movl    %ecx, -20(%rbp)
    .loc    1 18 9                  ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:18:9
    movq    %rax, %rdi
    callq   _objc_autoreleasePoolPop
    jmp LBB0_1
Ltmp8:
LBB0_3:
    .loc    1 19 1                  ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:19:1
    addq    $32, %rsp
    popq    %rbp
    ret
Ltmp9:
Lfunc_end0:
    .file   2 "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObject.h"
    .file   3 "/Users/Parag/Desktop/Test/Test/AppDelegate.h"
    .cfi_endproc

    .align  4, 0x90
"-[AppDelegate bFunc]":                 ## @"\01-[AppDelegate bFunc]"
    .cfi_startproc
Lfunc_begin1:
    .loc    1 20 0                  ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:20:0
## BB#0:
    pushq   %rbp
Ltmp12:
    .cfi_def_cfa_offset 16
Ltmp13:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp14:
    .cfi_def_cfa_register %rbp
    subq    $32, %rsp
    movq    %rdi, -8(%rbp)
    movq    %rsi, -16(%rbp)
    .loc    1 22 12 prologue_end    ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:22:12
Ltmp15:
    movl    $0, -20(%rbp)
LBB1_1:                                 ## =>This Inner Loop Header: Depth=1
    .loc    1 23 5                  ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:23:5
Ltmp16:
    cmpl    $5, -20(%rbp)
    jge LBB1_3
## BB#2:                                ##   in Loop: Header=BB1_1 Depth=1
    .loc    1 25 26                 ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:25:26
Ltmp17:
    callq   _objc_autoreleasePoolPush
    .loc    1 26 14                 ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:26:14
    movl    -20(%rbp), %ecx
    addl    $1, %ecx
    movl    %ecx, -20(%rbp)
    .loc    1 27 9                  ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:27:9
    movq    %rax, %rdi
    callq   _objc_autoreleasePoolPop
Ltmp18:
    .loc    1 28 5                  ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:28:5
    jmp LBB1_1
Ltmp19:
LBB1_3:
    .loc    1 29 1                  ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:29:1
    addq    $32, %rsp
    popq    %rbp
    ret
Ltmp20:
Lfunc_end1:
Run Code Online (Sandbox Code Playgroud)