繁体   English   中英

可以在没有__weak对象的块中传递[self anyFunction](iOS 5 + ARC)

[英]Possible to pass [self anyFunction] in blocks without __weak object (iOS 5 + ARC)

是否有可能在没有__weak对象的块中传递[self anyFunction]?

作为示例,这是来自System Framework的有效代码:

[UIView animateWithDuration:0.8 animations:^{
            //Do animationStuff
        } completion:^(BOOL finished) {
            [self anyFunction];
 }];

您可以在完成块中传递[self anyFunction]而不会发出警告。 但是如果使用完成块编写自己的方法,则会出现以下警告: 在此块中强烈捕获“self”可能会导致保留周期

工作解决方案非常简单(iOS 5 + ARC)。 在块声明之前:

__weak MyClass *weakSelf = self;

在完成块中你必须打电话:

[weakSelf anyFunction];

但是,回到我的问题:为什么System Framework API中不需要使用__weak对象并且在没有任何警告的情况下使用self 以及如何在块中不需要__weak对象的情况下实现方法?

感谢你的付出。

抛出错误的块是捕获拥有块的对象的块。 例如

[object performBlock:^{
    [object performSomeAction]; // Will raise a warning
}];

要么

[self performBlock:^{
    [self doSomething];    // Will raise a warning
}];

[self performBlock:^{
    [object doSomething];    // <-- No problem here
}];   

因为一个对象保留了它的块,一个块保留了它的对象。 因此,在这两种情况下,执行块的对象拥有块,该块也拥有该对象。 所以你有一个循环 - 一个保留周期。 这意味着内存泄露。

在您给出的示例中 - 您正在查看类方法 您在UIView类上调用块,而不是UIView对象。 类没有与之关联的内存。 你可能正在从一个控制器调用这个函数,所以块保留了self引用,但是没有循环,因为self没有保留块。

就像你可能注意到的那样,并非所有在块中使用的对象都需要被弱引用 - 只是导致保留周期的对象。

对于我需要使用或不使用ARC进行编译的代码,或者有或没有更新的编译器,我执行以下操作...功能上它与您已经列出的相同,但它避免了_weak并且也避免了保留释放周期:

//
// FOR NON-ARC PROJECTS
//
__block __typeof__(self) bself = self;
[someObject doThingWithBlock:^(id result){
    if (!bself)
        return;
    bself.thingWhich = result;
}];

///
// FOR ARC PROJECTS
//
__weak MyClass *bself = self;
[someObject doThingWithBlock:^(id result){
    if (!bself) 
        return;
    bself.thingWhich = result;
}];

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM