更新了问题我让情况更加清晰,因此您“需要”从块中访问原始值。
我不知道以下代码是否有任何实际用途,但仅仅为了学习和实验,请考虑以下内容:
__block int one = 1;
int(^capture)() = ^{
int copiedOne = one; // Copy one
++one; // Add one
return copiedOne;
};
NSLog(@"one: %i", one); // one = 1
NSLog(@"copied one: %i", capture()); // Returns copiedOne = 1, one is now 2
NSLog(@"one after calling block: %i", one); // one = 2
one += 10; // one = 12
NSLog(@"one: %i", one); // Prints 12
NSLog(@"copied one: %i", capture()); // Returns copiedOne = 12, one is now 13
NSLog(@"one after calling block: %i", one); // one = 13
如果你想保持块内的初始值1,但也能够修改块内的one
(我不知道。也许有一天你可能需要这种行为),还有另外一种方法,就是将一个值封装在静态NSNumber
变量中,如下所示?
如果one
是ClassA
实例的私有属性,则可能需要此行为,但您需要ClassB
的实例来更新ClassA
实例的属性获得one
的原始值。您可以从capture
调用ClassB
并实现上述行为,同时仍然可以访问one
的属性ClassA
的原始值。
__block int one = 1;
int(^capture)() = ^{
static NSNumber *copiedOne = nil;
if (!copiedOne) {
copiedOne = @(one); // Copy one
}
++one; // Add one
return [copiedOne intValue];
};
NSLog(@"one: %i", one); // one = 1
NSLog(@"copied one: %i", capture()); // Returns copiedOne = 1, one is now 2
NSLog(@"one after calling block: %i", one); // one = 2
one += 10; // one = 12
NSLog(@"one: %i", one); // Prints 12
NSLog(@"copied one: %i", capture()); // Returns copiedOne = 1, one is now 13
NSLog(@"one after calling block: %i", one); // one = 13
答案 0 :(得分:0)
该块捕获在其周围声明的任何变量值,无论您是否使用__block声明。 __block声明允许您更改该变量内的值。它本质上改变了块本身看到该变量的方式,没有__block声明它将被视为块的静态。
因此,将原始的一个变量保留原样并且不将其声明为__block是有意义的。然后在创建块之前复制该变量,并使其成为您要修改的块。
int one = 1;
__block copiedOne = one;
void(^capture)() = ^{
++CopiedOne; // Add one
NSLog(@"copiedOne: %i, one: %i", copiedOne, one);
};
来自Apple Docs ......
因为Integer被声明为__block变量,所以它的存储与块声明共享。