2015-09-09 1 views
0

Скажем, у меня есть следующий синглтон:Содержит ли ссылка на однопользовательский sharedInstance цикл сохранения?

@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 

Если йоЗотеЬЫпд содержали этот код:

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

... было бы создать сохранить цикл, поскольку ABCSingleton владеет mainViewController, владеющей tapBlock, который владеет ABCSingleton.

Что делать, если вместо использования self, я использовал sharedInstance?

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

Будет ли он создавать цикл удержания? (Объяснение относительно того, почему, или почему бы и нет, было бы оценено!)

+0

Это вызовет цикл удержания, но вы должны спросить себя, имеет ли значение цикл удержания на одном элементе. Вы определили сильную статическую ссылку на нее, поэтому она никогда не уходит. – Fabian

+0

@Fabian: Хороший момент, я обновил пример, чтобы показать, почему я специально стараюсь не создавать цикл сохранения. Я не хочу, чтобы mainViewController оставался в памяти навсегда. – Senseful

+0

Опять же, цикл сохранения не имеет значения. '@property (неатомный, сильный) ABCViewController * mainViewController;' сделает так, что 'mainViewController' никогда не будет выпущен, если вы явно не отключите его. – Fabian

ответ

2

К конкретному вопросу, это цикл удержания в первом случае и эквивалентен циклу удержания во втором случае (эквивалент в этом mainViewController никогда не будет выпущен).

Это указывает на более глубокую проблему с дизайном. Синглтон никогда не должен ссылаться на контроллер вида. Синглтоны по своей природе являются объектами модели. Объекты модели никогда не должны ссылаться на объекты контроллера напрямую. См. Model-View-Controller для введения. Это ключевой шаблон дизайна в Cocoa.

Вместо этого контроллер представления должен знать о модели (в этом случае синглтон). doSomething должен изменить модель, и контроллер вида, когда он появится на экране, должен прочитать модель для установки tapBlock. Контроллер представления также может наблюдать модель (через KVO, уведомления или делегирование), пока он находится на экране, чтобы узнать, когда нужно изменить его значения.

Смежные вопросы