Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iOS>&燃气轮机;积木>&燃气轮机;更改块外部变量的值_Ios_Objective C_Block_Variable Assignment_Objective C Blocks - Fatal编程技术网

iOS>&燃气轮机;积木>&燃气轮机;更改块外部变量的值

iOS>&燃气轮机;积木>&燃气轮机;更改块外部变量的值,ios,objective-c,block,variable-assignment,objective-c-blocks,Ios,Objective C,Block,Variable Assignment,Objective C Blocks,我熟悉使变量在块内“可赋值”的\uu block语句。 但是我看到,当使用一些Objective-C特性(在方法中使用块作为参数)时,一些变量是可赋值的,即使它们没有用这个\uu block语句声明 以下是两个代码,例如: [UIView animateWithDuration:2 animations:^ { self.animatedView.backgroundColor = [UIColor blueColor]; self.animated

我熟悉使变量在块内“可赋值”的
\uu block
语句。 但是我看到,当使用一些Objective-C特性(在方法中使用块作为参数)时,一些变量是可赋值的,即使它们没有用这个
\uu block
语句声明

以下是两个代码,例如:

[UIView animateWithDuration:2 animations:^
     {
         self.animatedView.backgroundColor = [UIColor blueColor];
         self.animatedView.center = CGPointMake(100, 100);
     }];
(animatedView是一个与IBOutlet连接的简单UIView)

我的问题是:我怎么能给UIView实例属性赋值?

我不是像我的mString那样寻址和更改对象

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

我希望“backgroundColor”的行为像我的imString一样,因为它是指向一个对象的指针,该对象被分配了一个新对象,不是吗


我在文档中找不到令人满意的解释。。。如果有人能给我提供一个,或者给我一个地址,我将不胜感激

这就是分配和使用之间的区别。方法调用的用法。您完全可以在实例上调用方法(
[mString appendString:@“Block”];//working
),但您不能在不标记变量的情况下分配(
imString=@“Imutable Hello Block”;//error
),告诉编译器应该启用它

此代码:

self.animatedView.backgroundColor = [UIColor blueColor];
仍然不是真正的赋值,而是“隐藏”方法调用。点表示法从来不是赋值,它是方法调用的语法糖。它实际上可以翻译为:

[[self animatedView] setBackgroundColor:[UIColor blueColor]];

赋值给局部变量和赋值给对象内部变量的区别在于它们在内存中的位置。基本上,它们会存在足够长的时间以发挥作用。这是堆栈上的数据和堆上的数据之间的差异。

要允许在块内更改变量,请使用_blockstorage type修饰符,请参见“the”

参考

以下规则适用于块内使用的变量:

  • 全局变量是可访问的,包括存在于封闭词法范围内的静态变量
  • 传递给块的参数是可访问的(就像函数的参数一样)。 封装词法作用域的局部堆栈(非静态)变量被捕获为常量变量
  • 它们的值在程序中的块表达式点处获取。在嵌套块中,从最近的封闭范围捕获值

  • 使用_块存储修饰符声明的封闭词法范围的局部变量由引用提供,因此是可变的

  • 任何更改都会反映在封闭词法范围中,包括在同一封闭词法范围内定义的任何其他块。这些将在“块存储类型”中进行更详细的讨论

  • 在块的词法范围内声明的局部变量,其行为与函数中的局部变量完全相同

  • 块的每次调用都提供该变量的新副本。这些变量可以依次用作常量或块中包含的块中的引用变量

  • 在第一个示例中,块“捕获”变量self-这是指向可保留对象的指针。在您的示例中,当您编写以下内容时,您不会修改自身:

    self.someProperty = someValue;
    
    self = nil;
    
    self的值仍然保持不变,也就是说,它仍然指向同一个对象

    例如,您可以修改self,如果您编写:

    self.someProperty = someValue;
    
    self = nil;
    

    你忘了提到这是一份来自解释一下这是如何应用于特定问题会更有帮助。我阅读了这份文件。。。但它仍然不能回答我的问题。以下哪些规则使未使用_块定义的UIView属性可在动画块内进行指定。为什么我的原语变量是不可赋值的,而UIView的原语属性是不可赋值的;为什么我不能将新对象分配给指针,除非我在声明中使用_块,UIView属性可以。好的。。。这个答案实际上指向某个地方。。。那么,我将一个对象传递给块的事实使得它的属性是可赋值的?我通过向我的类添加一个int属性和一个int ivar(没有_)块来测试它,我发现我可以在块中为它们分配一个新值。哪个原则/规则使属性/IVAR在区块内可分配?虽然定义块的方法中的局部变量不是?@OhadRegev,但您可以调用方法的事实是,调用方法不会改变接收方的指针(这里是self)(分配属性实际上就是这样)。注意self是一个指针,在调用方法之前,它的值可能类似于
    self等于0xabcd1230
    ,调用方法之后它仍然是一样的:
    self等于0xabcd1230
    @OhadRegev捕获变量的事实(这里的指针self的值是0xabcd1230)are const只是处理块或lambda时的一种常见约定。它们也可以被修改。所以“布尔隐藏”或“CGPoint中心”在它们后面持有IVAR这一事实没有任何区别?这是否意味着,由于它们是属性(通过Setter方法访问),因此会改变它们在内存中的分配方式?我还用我的类中声明的ivar(而不是方法中的局部变量)尝试了它,它也起了作用——而且它没有经过任何方法。该方法是一个副作用(因为缺少更好的术语)。不同之处在于内存位置。局部变量是在堆栈上创建的,因此除非您告诉编译器将它们复制到堆中,否则它们是不可访问的。当使数据在块内可用时,编译器还使用了许多“技巧”(指针和原语之间的路径不同)。这是一个深入的主题,请阅读