【问题标题】:Is there any way apart from the weak/strong dance to use an instance variable in a block?除了弱/强舞蹈之外,还有什么方法可以在块中使用实例变量?
【发布时间】:2015-11-09 19:23:42
【问题描述】:

在 Objective-C 中,您可能希望在块内使用实例变量,并将该块存储在对象本身中。如果你这样做,你会遇到相当麻烦的事情,以确保你不创建循环依赖,并消除所有编译器警告:

@implementation TestBlock {
    int someVariable;
    void (^someBlock)();
}

- (void) createBlock
{
    // ideally I would like to use:
    someBlock = ^{
        someVariable++;
    };

    // but in reality I need to use:
    TestBlock * __weak weakSelf = self;
    someBlock = ^{
        TestBlock *strongSelf = weakSelf;
        strongSelf->someVariable++;
    };
}

@end

如果使用weakSelf,而不是strongSelf,那么你会得到错误:

不允许取消引用 __weak 指针

如果直接使用self,则会创建一个保留循环。

我知道为什么需要这样做的背景,但是真的没有更简单的方法可以在块中使用实例变量吗?有什么实用的方法可以使这个更短、更易读吗?

【问题讨论】:

  • 您没有其他选项可以直接访问 ivar。但是您可以选择使用 ivar 周围的属性。然后您可以使用wealSelf 访问该属性。
  • 如果你必须访问 ivar,你可以使用“@weakify”和“@strongify”宏holko.pl/2015/05/31/weakify-strongify>,这使它更具可读性。
  • 关键是要避免块作为 ivars。例如,您可以重新设计您的类,使其具有接受块作为参数的方法。
  • @ReinhardMänner 我不知道你提到的weakify-strongify 宏,这是一个有趣的想法,我一定会尝试。至少它使发生的事情更加简洁明了。
  • @CouchDeveloper 像我在示例中显示的那样将块作为直接实例变量确实很少见。但是很常见的 iVar 带有另一个类的对象,它包含您提供给它的块。这将构成完全相同的问题。

标签: objective-c objective-c-blocks instance-variables weak-references


【解决方案1】:

如果您为您的 ivar 创建一个 property,您可以直接在 weak 引用上引用该属性(尽管它实际上是一个方法调用)。如果您想直接访问实例变量,则必须按照您发布的代码中的 weak/strong 跳舞。

我意识到这是一个 Objective-C 问题,但值得注意的是,这是 capture lists 在 Swift 中解决的问题。

【讨论】:

  • 当然,当你只想增加一个 int 时的属性访问是相当痛苦的:[self setSomeVariable:[self someVariable] + 1];
  • self.someVariable = self.someVariable + 1;是有效的Objective-C属性语法
  • self.someVariable++ 甚至是有效的语法。但就问题的前提而言,直接创建 ivar 是一个好主意的情况非常罕见。使用-> 访问它是一个好主意,这种情况更不常见。属性是实现所有这些的正确方法。 (尽管在大多数情况下,属性仍然需要一些强/弱的舞蹈。正如 CouchDeveloper 建议的那样,如果可以的话,通常最好尝试围绕需要它进行设计。)
  • 确实如此,这当然是最好的方法。不过,有些地方你别无选择,只能跳 strong/weak 跳舞(比如 NSNotificationCenter 基于块的 API)。
  • 使它成为一个属性将减少一半的问题(你仍然需要它的薄弱部分)。但我真的不喜欢纯粹出于技术原因使用属性。属性对于类的公共变量非常有用,但对于它的私有数据,我看不出使用它们的真正概念原因。为此,我觉得使用 iVar 更清晰、更直接、更高效。
猜你喜欢
  • 1970-01-01
  • 2018-01-01
  • 2015-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-28
相关资源
最近更新 更多