简体   繁体   English

引用单例的sharedInstance是否会创建保留周期?

[英]Does referencing a singleton's sharedInstance create a retain cycle?

Say I have the following singleton: 说我有以下单身人士:

@interface ABCSingleton: NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, strong) ABCViewController *mainViewController;
@end

@implementation ABCSingleton
+ (ABCSingleton *)sharedInstance {
    static ABCSingleton *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [ABCSingleton new];
    });
    return instance;
}
- (void)doSomething {
}
@end

If doSomething contained this code: 如果doSomething包含以下代码:

- (void)doSomething {
    self.mainViewController.tapBlock = ^() {
        self.name = @"abc";
    };
}

... it would create a retain cycle since ABCSingleton owns mainViewController, which owns tapBlock, which owns ABCSingleton. ...这将创建一个保留周期,因为ABCSingleton拥有mainViewController,而mainViewController拥有tapBlock,而tapBlock拥有ABCSingleton。

What if instead of using self , I used sharedInstance ? 如果我使用sharedInstance而不是使用self怎么

- (void)doSomething {
    self.mainViewController.tapBlock = ^() {
        [ABCSingleton sharedInstance].name = @"abc";
    };
}

Would it still create a retain cycle? 还会创建保留周期吗? (An explanation as to why, or why not, would be appreciated!) (有关原因或原因的解释将不胜感激!)

To the specific question, this is a retain loop in the first case, and equivalent to a retain loop in the second case (equivalent in that mainViewController will never be released). 对于特定的问题,这是第一种情况下的保留循环,等效于第二种情况下的保留循环(等效于该mainViewController将永远不会释放)。

This indicates a deeper design problem. 这表明存在更深的设计问题。 A singleton should never reference a view controller. 单例永远不要引用视图控制器。 Singletons are by nature model objects. 单例自然是模型对象。 Model objects should never reference controller objects directly. 模型对象绝对不能直接引用控制器对象。 See Model-View-Controller for an introduction. 有关介绍,请参见Model-View-Controller This is a key design pattern in Cocoa. 这是可可粉中的关键设计模式。

Instead, the view controller should know about the model (the singleton in this case). 相反,视图控制器应该知道模型(在这种情况下为单例)。 doSomething should modify the model, and the view controller, when it comes on the screen, should read the model to set tapBlock . doSomething应该修改模型,并且视图控制器出现在屏幕上时,应该读取模型以设置tapBlock The view controller can also observe the model (via KVO, notifications, or delegation) while it is onscreen to know when to change its values. 视图控制器还可以在屏幕上观察模型(通过KVO,通知或委托),以了解何时更改其值。

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

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