在Objective-c模块中,我是否需要将弱/强自我传递给助手?
在块中,是否需要将某些版本的self-to-helper方法传递给其他方法 在本例中,publicMethod()使用strongSelf调用_privateHelper 但是,_privateheloper()正在使用self调用_secondprivateheloper()。这样可以吗?还是我应该把在Objective-c模块中,我是否需要将弱/强自我传递给助手?,objective-c,Objective C,在块中,是否需要将某些版本的self-to-helper方法传递给其他方法 在本例中,publicMethod()使用strongSelf调用_privateHelper 但是,_privateheloper()正在使用self调用_secondprivateheloper()。这样可以吗?还是我应该把strongSelf传给助手 - (void)publicMethod { auto __weak weakSelf = self; dispatch_sync(dispat
strongSelf
传给助手
- (void)publicMethod
{
auto __weak weakSelf = self;
dispatch_sync(dispatch_get_main_queue(), ^{
auto __strong strongSelf = weakSelf;
if (!strongSelf) {
return;
}
[strongSelf _privateHelper];
});
}
- (void)_privateHelper
{
[self _secondPrivateHelper]; // <-- what version of `self` is sending the message here? I'm assuming the copied `strongSelf` from above.
}
- (void)_secondPrivateHelper
{
NSLog(@"Hello, World");
}
-(void)publicMethod
{
自动u_弱弱自我=自我;
调度同步(调度获取主队列()^{
自动_uSTRONG strong SELF=弱自我;
如果(!strongSelf){
返回;
}
[strongSelf_privateHelper];
});
}
-(无效)(私家佣工)
{
[self_secondPrivateHelper];//TLDR
何时使用strong
或weak
取决于块的使用方式。在代码中strong
和weak
并不重要,但我将给出一个重要的示例,并解释如何使用weak
我认为你在考虑错误的事情。在你的例子中,所有指向<代码>的自我>代码>可以(也应该)是<代码>强< /Cord>。你不需要在这里跳舞,只有当你创建保留循环时,你应该考虑使用<代码>弱< /代码>。
在您的情况下,请注意,当您在块内时,您需要一个指向
self
的strong
指针。如果您有weak
指针,则当self
为nil
时,块将变得多余。要获得强指针,只需将块更改为
... ^{
[self _privateHelper];
});
现在(以及在您的原始代码中)您在\u private helper
和\u secondprivate helper
中都有一个strong
指向self
的指针
但这不是问题所在
保留周期
假设你有一个ivar
@property (strong,nonatomic) void ( ^ block )( void );
直到现在,您才有潜在的问题,您可能需要使用弱的指针。原因是如果您的代码中有
self.block = ^{ [self _privateHelper]; };
块将保留一个指向self
的strong
指针。同时,self
通过ivar在块上保留一个strong
指针。您能看到保留周期吗?块和self
都不会自动释放,因为它们都保留对e其他
修复它
您可以将ivar更改为弱
,在这种情况下,您可以中断循环。如果块超出范围,则弱
ivar将变为零
,并且自身
上没有保留
你也可以这样做
self.block = ^ { [weakSelf _privateHelper]; };
在块内部中断循环。现在如果self
超出范围,块将不再保持它,并且self
上也没有保留循环
使用了这两种修复程序-在UI环境中,许多IVAR将弱
,以防止标签在vc上保留strong
引用,而vc也在标签上保留strong
引用
在使用块时,通常只有在可能有保留周期的情况下,才在块内使用weak
指针指向self
。这通常不是问题,在代码中也不是问题,因为self
不保留块。因此,通常情况下,您的助手块可能不受strong
的影响>指向self
的指针。仅当self
和块正在创建一个保留循环时,才需要跳舞
最后,第三种解决方法是自己将ivar设置为nil
if ( self.block )
{
self.block (); // Execute block
self.block = nil;
}
这有时也有意义,例如,当您希望保留块和self
直到块执行时。在这里,您可以通过将ivar设置为nil
手动释放ivar,之后它不再保留self
,并且循环被手动中断
您甚至可以在块内执行此操作,例如,将块更改为
self.block = ^ { [self _privateHelper]; self.block = nil; /* release when done */ };