【问题标题】:Retain cycles with a singleton in Objective-C在 Objective-C 中使用单例保留循环
【发布时间】:2019-03-16 01:42:11
【问题描述】:

我有一个名为 MyManager 的单例类。我在其块内使用 self:requestSomeInfo 和 requestSomeInfoWithString。 requestSomeInfoWithString 方法获取 self.string 作为参数。 此代码是否会导致两个块中的保留循环?

该项目使用 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

【问题讨论】:

    标签: objective-c memory-management singleton


    【解决方案1】:

    您的描述没有提到MyClass,但您的代码片段却提到了。通过代码片段,您在MyClass 中有方法,它会调用MyManager 中的方法。这些调用直接将块作为参数传递,而不会将引用存储在对这些块的实例变量中;您没有显示MyManager 是否在其实例变量中存储了对它接收到的块的引用,但假设它确实存在是合理的。

    传递的块使用self,它引用了创建块的MyClass 的实例。

    因此,从 MyManager 方法中将恢复的块引用存储到实例变量中的点,您具有以下引用链:

    shared -> 你的MyManager 实例

    MyManager 实例 -> 传入的块

    传递的块 -> 引用创建它的MyClass 实例

    这不是一个引用循环,所以除非你的真实代码中有更多的对象间引用,否则你没有循环。

    引用循环本身并不坏,它们可以在正常的程序执行过程中创建,有时对于保持适当的对象存活至关重要;一个循环可能是暂时的/具有有限寿命,之后循环中的至少一个链接被破坏。只有当引用循环无意导致对象实例超出其所需的生命周期...

    这最终将我们带到了您的代码中。您有一个MyManager共享实例,它可能从它的创建点一直存在,直到您的程序完成。在那种情况下,您存储对块的引用,而这些块存储对MyClass 实例的引用......这是您可能无意中“泄漏”的地方;如果您的 MyManager 方法没有擦除(将 nil 存储到)一旦不再需要引用这些块的实例变量(可能在引用的块被调用后立即),那么您可能会长期无意引用 @ 987654336@ 早已被丢弃的实例。删除这些块引用一旦使用,可能性就消失了。

    希望一切都有意义!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-29
      • 2015-04-24
      • 2014-07-04
      • 1970-01-01
      相关资源
      最近更新 更多