我有一个名为MyManager
的单例类。我在其 block 内使用 self:requestSomeInfo 和 requestSomeInfoWithString。
requestSomeInfoWithString 方法获取 self.string 作为参数。
此代码是否会导致两个 block 中出现循环保留?
该项目是与 ARC 合作的。
@interface MyManager : NSObject
+ (instancetype)sharedInstance;
- (void)requestSomeInfo:(void (^)(BOOL success))completion;
- (void)requestSomeInfoWithString:(NSString *)string completion:(void (^)(BOOL success))completion;
@end
@implementation MyManager
+ (instancetype)sharedInstance {
static MyManager *shared = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
shared = [MyManager new];
});
return shared;
}
@end
@interface MyClass
@property string;
@end
@implementation MyClass
.....
[[MyManager sharedInstance] requestSomeInfo:^(BOOL success) {
if (success) {
[self someAction];
}
}];
[[MyManager sharedInstance] requestSomeInfoWithString:self.string completion:^(BOOL success) {
if (success) {
[self someAction];
}
}];
.....
@end
最佳答案
您的描述没有提到MyClass
,但您的代码片段却提到了。通过代码片段,您可以在 MyClass
中找到方法,这些方法会调用 MyManager
中的方法。这些调用直接将 block 作为参数传递,而无需在实例变量中存储对这些 block 的引用;您没有显示 MyManager
是否在其实例变量中存储对其接收的 block 的引用,但可以合理地假设它确实如此。
传递的 block 使用 self
,它引用创建该 block 的 MyClass
实例。
因此,从 MyManager
方法中将恢复的 block 引用存储到实例变量中的点开始,您将拥有以下引用链:
shared
-> yourMyManager
instancethe
MyManager
instance -> the passed in blockthe passed block -> references the
MyClass
instance which created it
这不是引用循环,因此除非您在实际代码中有更多对象间引用,否则就没有循环。
引用循环本身并不坏,它们可以在正常的程序执行过程中创建,有时对于保持适当的对象处于事件状态可能至关重要;一个循环可以是临时的/具有有限的生命周期,之后该循环中的至少一个链接被破坏。当引用循环无意中导致对象实例超出其所需的生命周期时,它才会成为坏的保留循环...
这最终让我们看到了您的代码。您有一个 MyManager
的共享实例,它可能从创建时起一直存在到程序完成为止。在这种情况下,您存储对 block 的引用,而这些 block 存储对 MyClass
实例的引用...这是您可能会无意中“泄漏”的地方;如果您的 MyManager
方法在不再需要这些引用时(可能在调用引用的 block 后立即)不会删除(将 nil
存储到)引用这些 block 的实例变量那么您可能会长期无意地引用早已被丢弃的 MyClass
实例。删除那些曾经使用过的 block 引用,这种可能性就消失了。
希望一切都有意义!
关于objective-c - Objective-C 中使用单例保留循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52752181/