可以在没有__weak对象(iOS 5 + ARC)的情况下通过

是否可以传递[self的任何function]块没有__weak对象从自我?

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

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

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

一个可行的解决scheme非常简单(iOS 5 + ARC)。 在块声明之前:

 __weak MyClass *weakSelf = self; 

并在完成块,你必须打电话:

 [weakSelf anyFunction]; 

但是,回到我的问题:为什么没有必要在系统框架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引用被块保留,但是没有循环,因为自身没有保留块。

以同样的方式,你可能已经注意到,并不是所有在块中使用的对象都需要弱引用 – 就是那些引起保留周期的对象。

在需要使用或不使用ARC进行编译的代码上,或者使用或不使用较新的编译器时,我会执行以下…function上与已经列出的function相同,但它避免了_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; }];