【问题标题】:Capturing an Objective-C object weakly within C block without declaring an explicit __weak or __block variable在 C 块中弱捕获 Objective-C 对象而不声明显式 __weak 或 __block 变量
【发布时间】:2014-11-29 15:37:31
【问题描述】:

我正在 C 块中捕获一个方法范围的对象,我想避免保留循环。这是我的代码:(balloon 是在我当前方法中创建的自定义视图)

balloon.onAddedToViewHierarchy = ^{
        CGRect globalRect = [[UIApplication sharedApplication].keyWindow convertRect:self.frame fromView:self.superview];
        CGRect targetFrame = CGRectMake(20, 0, SCREEN_WIDTH - 40, 60);
        targetFrame.origin.y = below ? globalRect.origin.y + globalRect.size.height + 10 : globalRect.origin.y - 10 - 60/*height*/;
        balloon.frame = globalRect;//targetFrame;
    };

在最后一行 (balloon.frame = globalRect;) 我被告知在块中捕获 balloon 将导致保留周期。我知道 ARC、所有权、保留计数等,我知道原因。我只是在寻找一种隐式摆脱保留balloon 的方法(通过从其他地方引用它已经保证被保留)并使用__weak 指针或__block(如果合适)。我知道我可以做到:

__weak UIView *weakBalloon = balloon;
balloon.onAddedToViewHierarchy = ^{
        CGRect globalRect = [[UIApplication sharedApplication].keyWindow convertRect:self.frame fromView:self.superview];
        CGRect targetFrame = CGRectMake(20, 0, SCREEN_WIDTH - 40, 60);
        targetFrame.origin.y = below ? globalRect.origin.y + globalRect.size.height + 10 : globalRect.origin.y - 10 - 60/*height*/;
        weakBalloon.frame = globalRect;//targetFrame;
    };

但实际上我正在探索在不显式创建新指针的情况下实现相同行为的方法。我正在寻找这样的东西:(它不会编译,只是一个演示)

balloon.onAddedToViewHierarchy = ^{
        CGRect globalRect = [[UIApplication sharedApplication].keyWindow convertRect:self.frame fromView:self.superview];
        CGRect targetFrame = CGRectMake(20, 0, SCREEN_WIDTH - 40, 60);
        targetFrame.origin.y = below ? globalRect.origin.y + globalRect.size.height + 10 : globalRect.origin.y - 10 - 60/*height*/;
        ((__weak UIView*)balloon).frame = globalRect;//targetFrame;
    };

有类似的可能吗?我知道声明一个__weak 变量并没有错,它会完美地工作。我只是好奇这种隐含行为是否可能。

【问题讨论】:

    标签: objective-c automatic-ref-counting objective-c-blocks weak-references


    【解决方案1】:

    考虑使用@weakify@strongify 宏,包含在Reactive CocoaExtended Objective-C Library 中。

    有关这一点的演示,请参阅 Ray Wenderlich 的 part 2 of 2 discussion about Reactive Cocoa 中的避免保留周期讨论。

    那篇文章提供了以下示例:

    __weak RWSearchFormViewController *bself = self; // Capture the weak reference
    
    [[self.searchText.rac_textSignal map:^id(NSString *text) {
        return [self isValidSearchText:text] ? [UIColor whiteColor] : [UIColor yellowColor];
      }]
      subscribeNext:^(UIColor *color) {
        bself.searchText.backgroundColor = color;
      }];
    

    他们继续建议可以替换为:

    @weakify(self)
    [[self.searchText.rac_textSignal map:^id(NSString *text) {
        return [self isValidSearchText:text] ? [UIColor whiteColor] : [UIColor yellowColor];
      }]
      subscribeNext:^(UIColor *color) {
        @strongify(self)
        self.searchText.backgroundColor = color;
      }];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多