我在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
变量没有错,它会完美地工作。我只是好奇这种隐含的行为是否可能。
考虑使用 Reactive Cocoa 或扩展 Objective-C 库中包含的 @weakify
和 @strongify
宏。
有关此演示,请参阅 Ray Wenderlich 中的避免保留周期讨论第 2 部分,共 2 部分
,讨论反应性可可。该文章提供了以下示例:
__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;
}];