首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >__weak自块

__weak自块
EN

Stack Overflow用户
提问于 2015-12-04 00:20:15
回答 2查看 1.4K关注 0票数 1

我有关于自我的__weak参考。我是否需要__weak参考controller2和控制器3,这也是在竞赛块中引用的?

代码语言:javascript
复制
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的弱引用?

代码语言:javascript
复制
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];
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-12-04 01:05:47

声明和使用weak副本是无害的(在本例中),但是块的引用的none必须是weak

这个问题是一个常见误解的症状:块所引用的所有对象都被块保持为强有力的引用(保留)。如果这些对象保留了对块的强烈引用,那么您就有了一个保留周期。

就像听起来一样,保留周期是指对象之间强烈地相互引用,或者直接引用:

代码语言:javascript
复制
block ---> objectA ---> block  ("--->" means retains)

..。或间接:

代码语言:javascript
复制
block ---> objectA ---> objectB ---> block

保留周期是不好的,因为系统不会释放其他对象保留的对象。因此,当我们试图释放块时,我们不能这样做,因为(在直接情况下)它是由objectA保留的,而不能释放objectA,因为它是由块保留的。

简单的解决方法是声明指针的weak副本,告诉块本质上“不要保留这个对象,我保证它会比块更长”。

查看OP代码,传递给presentViewController的块根本没有保留。它被保存足够长的时间来完成演示,在动画完成后调用,然后丢弃。由于块所引用的对象中没有一个保留该块的副本,因此不存在保留周期的风险,并且根本不需要任何weak引用。

代码语言:javascript
复制
// 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,为了避免保留周期,必须使用弱副本。

票数 3
EN

Stack Overflow用户

发布于 2016-08-12 09:41:52

除了@danh的响应之外,当您声明一个块属性时,将它作为复制来执行,因为块从堆栈开始,它们需要移动到堆中,以便保持对它们的强烈引用。

代码语言:javascript
复制
typedef void(^MyCustomBlock)(void);

@property (nonatomic, copy) MyCustomBlock customBlock;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34078789

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档