Objective-C阻止并捕获自我

时间:2016-08-25 06:11:36

标签: objective-c objective-c-blocks

我遇到过关键字'阻止'和'自我'似乎是关于保留周期。但这不是问题......

我的问题是:为什么在块外可见对self的属性进行更改?我认为价值观应该被捕获&#39 ;?也就是说,块引用是原始对象的副本?

这里有一些代码来说明我的困境:

int a = 1;
self.someProperty.name = @"Foo";

[self.someProperty someMethodWithCompletionHandler:^() {
  NSLog(@"%d", a);
  NSLog(@"%@", self.someProperty.name);
}];

a = 2;
self.someProperty.name = @"Bar";

我得到的输出是:

1
Bar

2 个答案:

答案 0 :(得分:2)

捕获值,这就是块中a1的原因。

但你的字符串是一个对象。捕获指针(只是一个地址),但它指向的字符串的值已经改变。这就是你看“Bar”的原因。

答案 1 :(得分:2)

C,并且通过扩展,Objective-C使用按值语义。也就是说,当将参数传递给函数时,变量值的副本将传递给被调用者。允许被调用者更改本已复制的原始变量的方法是传递指针。被调用者现在可以直接访问原始变量引用的内存位置。

int a = 1;  // a is stored at memory location 0xABCD

f(a); // The value of a (1) is passed to f().  This copy is at 0xCDEF.

void f(int a) {
    // The value at 0xCDEF is now 10, but 0xABCD (the "original") is untouched.
    a = 10;
}

g(&a);  // The address of "a" is passed.  This is the value 0xABCD.

void g(int *a) {
    // This dereferences the pointer and changes the value at that location to 10.
    // As the value of the pointer is the address of "a", the original variable "a"
    // now has the new value of 10.
    *a = 10;
}

Objective-C中的块以相同的方式工作。捕获的值与作为参数传递给函数的类型相同。这意味着传递非指针将不允许原始变量更改,而传递指针将允许更改这些位置的内存。由于对象只能通过指针访问,因此每个对象变量都是一个指针。这允许块以与上面示例中的g()相同的方式操纵对象,可以操纵"原始" a变量。