【问题标题】:Objective C block works by passing in pointer of pointers?Objective C 块通过传入指针的指针来工作?
【发布时间】:2012-09-27 11:43:29
【问题描述】:

运行此代码并在控制台中获取x is 11。改变方法范围之外的变量状态对我来说就像一个块行为。区块是这样工作的吗?

- (void)viewDidLoad
{
    NSNumber *x = [NSNumber numberWithInt:5];
    [self doSomethingWithNumber:&x];
    NSLog(@"x is %@ \n",x);

}

- (BOOL)doSomethingWithNumber:(NSNumber**)aNumber
{
    *aNumber = [NSNumber numberWithInt:11];
    return YES;
}

【问题讨论】:

  • 嗨,谁反对这个问题,请发表评论。我认为这是一个值得回答的真实问题。

标签: objective-c pointers pass-by-reference


【解决方案1】:

尽管您的示例的非正统语法 - 我认为这只是为了说明一点 - 块从定义它们的词法范围捕获状态是正确的。有关内部结构的更多信息,请查看 Mark Dalrymple 的 this post 块内部结构。

通常,来自周围作用域的变量在块内具有按值传递语义,并具有 __block 修饰符的按引用传递语义。因此,这将 抛出异常 无法编译 (EDIT 2012-09-27 20-52-51)

#import <Foundation/Foundation.h>

typedef int (^IntBlock)();

    int main(int argc, char *argv[]) {
        NSAutoreleasePool *p = [[NSAutoreleasePool alloc] init];

        int n = 5;
        IntBlock alwaysEleven = ^{ 
            n++; 
            printf("n inside the block: %d\n",n);
            return 11;
        };
        int d = alwaysEleven(n);
        printf("result = %d, n = %d", d,n);

        [p release];
    }

但如果我们声明 __block int n = 5; 它不会。

@leo 建议开始使用 Blocks。如果您对块如何捕获状态以及所捕获状态的位置(在堆栈上直到 Block_copy())感兴趣,那么文档中的块编程主题值得一读。

【讨论】:

  • “通常,来自周围作用域的变量在块内具有按值传递语义,并具有 __block 修饰符的按引用传递语义。”这让我头脑清醒。非常感谢!
  • "因此,这会抛出异常" 我认为是编译错误
  • 但是按值捕获语义并不一定意味着您不能分配给它——这是一种语言选择。例如,对于 C++11 lambda,如果 lambda 声明为 mutable,则仍可以将按值捕获的变量分配给。
  • @NSBum,四个月后我回到这个问题,现在我真正理解了你的答案。学习需要耐心,也需要像你这样的人的帮助。再次感谢您。
【解决方案2】:

不,这就是指针的工作原理。如果你想用积木做一些事情,那么请关注 Apple 的 Getting Started with Blocks 或众多优秀教程之一 on the web

【讨论】:

  • 我知道块语法。我的问题是关于块的内部机制。更具体地说,块是否通过隐蔽地传入变量指针将变量的状态保持在周围的上下文中?
猜你喜欢
  • 1970-01-01
  • 2011-05-19
  • 1970-01-01
  • 2011-09-26
  • 2014-04-12
  • 2013-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多