在没有声明显式__weak或__block变量的情况下弱捕获C块中的Objective-C对象 [英] Capturing an Objective-C object weakly within C block without declaring an explicit __weak or __block variable

查看:89
本文介绍了在没有声明显式__weak或__block变量的情况下弱捕获C块中的Objective-C对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在C块中捕获方法范围的对象,并且我想避免保留周期.这是我的代码:(balloon是在当前方法中创建的自定义视图)

I am capturing a method-scoped object in a C block and I want to avoid retain cycles. Here is my code: (balloon is a custom view created within my current method)

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(如果适用).我知道我可以做到:

at the last line (balloon.frame = globalRect;) I am told that capturing balloon in block will lead to a retain cycle. I know about ARC, ownerships, retain counts etc and I know the reason. I am just looking for a way to implicitly get rid of retaining balloon (it's already guaranteed to be retained by being referenced from other places) and using a __weak pointer, or __block if appropriate. I know I can do this:

__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;
    };

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

But actually I'm exploring ways to implement the same behavior without explicitly creating a new pointer. I am looking for something like this: (it won't compile, just a demo)

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变量没有任何问题,它将很好地工作.我很好奇,是否有可能实现这种隐式行为.

Is something similar possible? I know there's nothing wrong with declaring a __weak variable, it will just work perfectly. I'm just curious that if such an implicit behavior is possible or not.

推荐答案

考虑使用@weakify和@strongify宏. "nofollow">反应性可可粉扩展的Objective-C库.

Consider using the @weakify and @strongify macros, included in Reactive Cocoa or the Extended Objective-C Library.

有关此操作的演示,请参阅Ray Wenderlich的

For demonstration of this, see the Avoiding Retain Cycles discussion in Ray Wenderlich's part 2 of 2 discussion about Reactive Cocoa.

该文章提供了以下示例:

That article provides the following example:

__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;
  }];

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

Which they go on to suggest could be replaced with:

@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;
  }];

这篇关于在没有声明显式__weak或__block变量的情况下弱捕获C块中的Objective-C对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆