iOS >>块>>更改块外部的变量值

Oha*_*gev 8 block objective-c variable-assignment ios objective-c-blocks

我熟悉__block在块中使变量"可赋值" 的语句.但是我发现当使用一些使用块作为方法中的参数的Objective-C特性时,一些变量是可分配的,即使它们没有用这个__block语句声明.

以下是2个代码:

[UIView animateWithDuration:2 animations:^
     {
         self.animatedView.backgroundColor = [UIColor blueColor];
         self.animatedView.center = CGPointMake(100, 100);
     }];
Run Code Online (Sandbox Code Playgroud)

(animatedView是一个与IBOutlet连接的简单UIView).

    int myInt = 10;
    NSMutableString* mString = [NSMutableString stringWithString:@"Mutable Hello"];
    NSString* imString = @"Imutable Hello";

    void (^myBlock)(void) = ^
    {
        [mString appendString:@" Block"]; //working
        imString = @"Imutable Hello Block"; //error
        myInt = 11; //error
    };
Run Code Online (Sandbox Code Playgroud)

我的问题是:为什么我可以为UIView实例属性赋值?

我不是在处理一个Object并改变它,就像我的mString一样.

我希望'center'属性的行为类似于myInt,因为它是直接访问的C结构,而不是指向对象的指针.

我希望'backgroundColor'的行为类似于我的imString,因为它是一个指向一个新对象的对象的指针,不是吗?

我在文档中找不到令人满意的解释...如果有人可以提供一个,或者解决我的问题,我将不胜感激.

Wai*_*ain 8

这是分配和使用之间的区别.用法是方法调用.您完全被允许在实例([mString appendString:@" Block"]; //working)上调用方法,但是如果imString = @"Imutable Hello Block"; //error没有标记变量来告诉编译器应该启用它,则不能赋值().

这段代码:

self.animatedView.backgroundColor = [UIColor blueColor];
Run Code Online (Sandbox Code Playgroud)

它仍然不是一个任务,它是一个"隐藏"的方法调用.点符号永远不是一个赋值,它是方法调用的语法糖.它实际上转换为:

[[self animatedView] setBackgroundColor:[UIColor blueColor]];
Run Code Online (Sandbox Code Playgroud)

分配给局部变量和对象内部变量的区别在于它们驻留在内存中的位置.基本上,它们的存在时间是否足够长.这是堆栈上和堆上的数据之间的区别.