【问题标题】:Write to variable outside of block in objective c写入目标c中块外的变量
【发布时间】:2015-01-06 21:21:28
【问题描述】:

我无法访问块外的变量(显然)。我似乎无法从块中返回值。我不敢相信使用类的属性是这里的最佳实践......

// Return true when failed
- (bool)myMethod:(XCUIElement *)element {
    bool fail = false;
    [self waitWithTimeout:timeout
                  handler:^(NSError *_Nullable error){
                  if (error != nil) {
                    // How do I assign to fail here?
                    fail = true;
                   }
    }
  return fail;
}

我该怎么做?

【问题讨论】:

  • 你能发布你的代码吗?我刚刚提交了一个答案,但再次阅读该问题,我不完全确定它是否解决了您的问题。
  • 您绝对应该学习“__block”关键字和“弱自我”模式。但是,根据我对您的问题的理解,您可能能够摆脱一些相当简单的事情。块将捕获当地人。如果没有 __block,您无法重新分配本地对象,但是您可以更改现有对象。做:NSMutableString *str = [NSMutableString 字符串]; (或者是stringWithString:@“”?)在块之外。然后在块 ^{ [str appendString: @"whatever!"];这应该可以正常工作。

标签: objective-c block


【解决方案1】:

访问块中的属性并没有错,但你必须小心。

默认情况下,块会强烈捕获变量。如果该类现在持有该块,您将获得一个保留周期。

为避免这种情况,您可以创建一个 self 的弱变量。在块中创建一个(默认)强变量来避免,对象自身将在处理块时被释放

__weak typeof(self) weakSelf = self;
self.testBlock = ^(NSInteger itemIndex) {
    typeof(self) strongSelf = weakSelf;
    if(strongSelf){
         strongSelf.foo = ....;
    }
};

如果要从周围作用域写入变量,请使用__block

__block NSUInteger foundIndex = NSNotFound;

[array enumerateObjectsUsingComparator:^(id obj, NSUInteger idx, *BOOL stop){
    if([obj ....]){
        foundIndex = idx;
        *stop = YES;
    }
}];

【讨论】:

    【解决方案2】:

    如果变量是块的本地变量,则使用 __block 声明它:

    __block NSString *blockString = @"Blocks are cool";
    

    一般来说,不用__block,你应该可以访问它们,但是如果你想改变变量的值,你需要它。

    【讨论】:

      猜你喜欢
      • 2022-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-20
      • 1970-01-01
      • 1970-01-01
      • 2010-11-03
      相关资源
      最近更新 更多