我有关于自我的__weak参考。我是否需要__weak参考controller2和控制器3,这也是在竞赛块中引用的?
UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
id controller1 = [sb instantiateViewControllerWithIdentifier:@"controller1"];
id controller2 = [sb instantiateViewControllerWithIdentifier:@"controller2"];
id controller3 = [sb instantiateViewControllerWithIdentifier:@"controller3"];
__weak typeof(self) weakSelf = self;
[self presentViewController:controller1 animated:YES completion:^{
[(UINavigationController *)weakSelf.parentViewController setViewControllers:@[controller2, controller3] animated:NO];
}];编辑,下面的代码呢?以下代码中的块是否需要对self的弱引用?
typedef void(^MyCustomBlock)(void);
@property (strong, readwrite, nonatomic) MyCustomBlock customBlock;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
__weak typeof(self) weakSelf = self;
self.customBlock = ^{
[(UINavigationController *)weakSelf.parentViewController setViewControllers:@[controller2, controller3] animated:NO];
};
[self presentViewController:controller1 animated:YES completion:self.customBlock];
}发布于 2015-12-04 01:05:47
声明和使用weak副本是无害的(在本例中),但是块的引用的none必须是weak。
这个问题是一个常见误解的症状:块所引用的所有对象都被块保持为强有力的引用(保留)。如果这些对象保留了对块的强烈引用,那么您就有了一个保留周期。
就像听起来一样,保留周期是指对象之间强烈地相互引用,或者直接引用:
block ---> objectA ---> block ("--->" means retains)..。或间接:
block ---> objectA ---> objectB ---> block保留周期是不好的,因为系统不会释放其他对象保留的对象。因此,当我们试图释放块时,我们不能这样做,因为(在直接情况下)它是由objectA保留的,而不能释放objectA,因为它是由块保留的。
简单的解决方法是声明指针的weak副本,告诉块本质上“不要保留这个对象,我保证它会比块更长”。
查看OP代码,传递给presentViewController的块根本没有保留。它被保存足够长的时间来完成演示,在动画完成后调用,然后丢弃。由于块所引用的对象中没有一个保留该块的副本,因此不存在保留周期的风险,并且根本不需要任何weak引用。
// initialize controller1, 2, 3
// no need for this
//__weak typeof(self) weakSelf = self;
[self presentViewController:controller1 animated:YES completion:^{
// perfectly safe...
[(UINavigationController *)self.parentViewController setViewControllers:@[controller2, controller3] animated:NO];
}];关于编辑中的附加代码,编辑:是的,在这种情况下,由于保留块并且块引用self,为了避免保留周期,必须使用弱副本。
发布于 2016-08-12 09:41:52
除了@danh的响应之外,当您声明一个块属性时,将它作为复制来执行,因为块从堆栈开始,它们需要移动到堆中,以便保持对它们的强烈引用。
typedef void(^MyCustomBlock)(void);
@property (nonatomic, copy) MyCustomBlock customBlock;https://stackoverflow.com/questions/34078789
复制相似问题