Block隐式保留了“自我";明确提及“自我"以表明这是预期的行为

Block隐式保留了“自我

问题描述:

给出以下内容:

- (void) someMethod
{
    dispatch_async(dispatch_get_main_queue(), ^{
        myTimer = [NSTimer scheduledTimerWithTimeInterval: 60
                                                           target: self
                                                         selector: @selector(doSomething)
                                                         userInfo: nil
                                                          repeats: NO];
    });
}

在私有接口中声明myTimer的位置:

Where myTimer is declared in a private interface:

@interface MyClass()
{
    NSTimer * myTimer;
}
@end

如何解决以下警告:

Block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior

根据我到目前为止发现的内容,大多数建议都涉及到诸如以下的内容:

From what I have found so far, most suggestions involve putting something such as:

- (void) someMethod
{
    __typeof__(self) __weak wself = self;
    dispatch_async(dispatch_get_main_queue(), ^{
        wself.myTimer = [NSTimer scheduledTimerWithTimeInterval: 60
                                                           target: self
                                                         selector: @selector(doSomething)
                                                         userInfo: nil
                                                          repeats: NO];
    });
}

除了myTimer是一个ivar,这意味着wself无法访问任何属性.

Except, that myTimer is an ivar, meaning wself does not have access to any properties.

我想我的问题是:

  1. 我要/应该在意吗?
  2. 我应该将myTimer声明为属性吗?

我在代码中经常使用ivars.我刚刚在项目中添加了-Weverything标志,以查看是否可以找到任何潜在的问题,这是迄今为止最常见的警告.尽管可以通过设置ivars属性来修复它,但我没有问题,但是我想确保在进行此操作之前能获得更好的理解.

I use ivars quite a bit through my code. I just added the -Weverything flag to my project to see if I can find any underlying issues and this is by far the most common warning. I have no problem going though and fixing it by making my ivars properties, but I want to make sure I get a better understanding before I do that.

self->myTimer替换myTimer将解决您的警告.

Replacing myTimer by self->myTimer would fix your warning.

在代码中使用iVar _iVar时,编译器将用self->_iVar替换代码,如果在块内使用它,则该块将捕获self而不是iVar本身.警告只是为了确保开发人员理解此行为.

When you use an iVar _iVar in the code, the compiler will replace the code by self->_iVar, and if you use it inside a block, the block will capture self instead of the iVar itself. The warning is just to make sure the the developer understand this behaviour.