Objective-C Blocks:如果从指向self的弱指针调用,则可以在外部方法中修改self吗?
您能从一个实例方法修改self吗?该实例方法是从块内的弱self指针调用的Objective-C Blocks:如果从指向self的弱指针调用,则可以在外部方法中修改self吗?,objective-c,memory-management,objective-c-blocks,Objective C,Memory Management,Objective C Blocks,您能从一个实例方法修改self吗?该实例方法是从块内的弱self指针调用的 -(void)someMethod:(AnotherClassName *)anObject { __weak MyClassName *weakSelf = self; [anObject requestSomethingWithCompletion:^{ [weakSelf updateSomething]; }]; } -(void)updateSomething {
-(void)someMethod:(AnotherClassName *)anObject {
__weak MyClassName *weakSelf = self;
[anObject requestSomethingWithCompletion:^{
[weakSelf updateSomething];
}];
}
-(void)updateSomething {
self.something = @"update"; // Will this cause a memory leak?
}
因此,基本上我是从我所在的同一个类中调用实例方法,但我是从弱指针调用实例方法,然后更改self
根据这一点,在块内如何调用self
上的方法,但不清楚我是否可以在该方法中直接修改self
如果你知道答案是基于你以前读过的东西,请包括来源
谢谢 您可以修改属性和调用方法。不会有内存泄漏 但是您的块现在不是线程安全的。如果
requestSomethingWithCompletion
将异步运行block,则在块执行期间可以释放类(self
),并且weakSelf
将变为零。这可能会导致问题(取决于块的功能)。避免这种情况的最佳做法是按照以下方式编写
-(void)someMethod:(AnotherClassName *)anObject {
__weak MyClassName *weakSelf = self;
[anObject requestSomethingWithCompletion:^{
MyClassName *strongSelf = weakSelf;
[strongSelf updateSomething];
}
}
-(void)updateSomething {
self.something = @"update"; // No leaks here!
}
您可以修改属性和调用方法。不会有内存泄漏 但是您的块现在不是线程安全的。如果
requestSomethingWithCompletion
将异步运行block,则在块执行期间可以释放类(self
),并且weakSelf
将变为零。这可能会导致问题(取决于块的功能)。避免这种情况的最佳做法是按照以下方式编写
-(void)someMethod:(AnotherClassName *)anObject {
__weak MyClassName *weakSelf = self;
[anObject requestSomethingWithCompletion:^{
MyClassName *strongSelf = weakSelf;
[strongSelf updateSomething];
}
}
-(void)updateSomething {
self.something = @"update"; // No leaks here!
}
挑剔但重要的区别:您不是在“修改”
self
,也不是在“更改”self
——其中self
是指向对象(而不是对象本身)的指针。相反,您将方法发送到self指向的对象,并可能修改该对象。这种区别对于理解块中涉及对象指针时的细微之处很重要;)@CouchDeveloper不会调用属性的setter,或者更具体地说发送消息[self-setSomething:@“update”]
来修改self指向的对象?好的,我想我现在明白了。类本身可以实现自己的setter,这可能会修改基础实例变量,也可能不会修改self。setter属性可能会修改对象,但是self本身,它是指向该对象的指针,保持不变。事实上,如果一个块捕获了指向任何对象(不仅仅是自身)的强指针,它就不能“修改”该指针,例如:obj=anotherObject代码>在块中会发出类似“无法修改变量'obj'”之类的编译器错误。Korey,整个主题更复杂,注释中无法进行彻底的解释。我最近写了一个可能也会有帮助的答案:挑剔但重要的区别:你不是在“修改”self
,也不是在“改变”self
——其中self
是指向对象的指针(而不是对象本身)。相反,您将方法发送到self指向的对象,并可能修改该对象。这种区别对于理解块中涉及对象指针时的细微之处很重要;)@CouchDeveloper不会调用属性的setter,或者更具体地说发送消息[self-setSomething:@“update”]
来修改self指向的对象?好的,我想我现在明白了。类本身可以实现自己的setter,这可能会修改基础实例变量,也可能不会修改self。setter属性可能会修改对象,但是self本身,它是指向该对象的指针,保持不变。事实上,如果一个块捕获了指向任何对象(不仅仅是自身)的强指针,它就不能“修改”该指针,例如:obj=anotherObject代码>在块中会发出类似“无法修改变量'obj'”之类的编译器错误。Korey,整个主题更复杂,注释中无法进行彻底的解释。我最近写了一个答案,这可能也会有所帮助:实际上,弱指针的实现方式保证了在OP的情况下,您不需要担心self是否已被释放。在这种情况下,解除弱指针的引用(意味着使用弱指针)将返回一个nil
值,并且可以安全地将消息发送到nil
。然而,您建议的习惯用法实际上是首选的,因为它实际上避免了这样一些微妙的问题,即当对弱指针进行多次解引用时,首先返回一个对象,然后再返回nil
——因为它同时被删除了。再次获取强指针可以安全地保留该对象。您的代码与OP的代码完全相同。请参阅“在对对象左值执行左值到右值转换时发生读取。对于_弱对象,当前指针对象将被保留,然后在当前完整表达式的末尾被释放。这必须根据赋值和指针对象的最终释放自动执行。”实际上,弱指针的实现方式保证了在OP的情况下,您不必担心self是否已被释放。在这种情况下,解除弱指针的引用(意味着使用弱指针)将返回一个nil
值,并且可以安全地将消息发送到nil
。然而,您建议的习惯用法实际上是首选的,因为它实际上避免了这样一些微妙的问题,即当对弱指针进行多次解引用时,首先返回一个对象,然后再返回nil
——因为它同时被删除了。再次获取强指针可以安全地保留该对象。您的代码与OP的代码完全相同。请参阅“在对对象左值执行左值到右值转换时发生读取。对于_弱对象,当前指针对象将保留,然后在当前完整表达式的末尾释放。这必须根据赋值和最终释放原子执行。”