2016-12-17 5 views
0

В настоящее время я работаю над приложением, которое использует четыре протокола для обмена данными между классами. Три работают нормально, но один все еще не работает. Я установил его так же, как и другие, но делегат всегда теряет свой идентификатор. Я совершенно новичок в Objective-C, поэтому я не могу разобраться в этом. Вот что я сделал:iOS - singleton не работает как делегат

У меня есть MainViewController.h с делегатом

@property (weak, nonatomic) id <PlayerProtocol> player; 

и MainViewController.m

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    [[Interface sharedInstance] Init]; 
    NSLog(@"Player ID: %@", _player); 
    NSLog(@"viewDidLoad: %@", self); 
} 

- (void)sedPlayer:(id) pointer{ //sed is no typo! 
    _player = pointer; 
    NSLog(@"sedPlayer ID: %@", _player); 
    NSLog(@"sedPlayer: %@", self); 
} 

+ (instancetype)sharedInstance { 
    static dispatch_once_t once; 
    static id sharedInstance; 
    dispatch_once(&once, ^{ 
     sharedInstance = [[self alloc] init]; 
    }); 
    return sharedInstance; 
} 

В Interface.m (NSObject)

- (void)Init { 
    [[MainViewController sharedInstance] sedPlayer:self]; 
} 

И, конечно, протокол.h, но это не представляет интереса, так как делегат делает эту проблему! Когда я запускаю код, который я получаю следующий вывод на консоль:

sedPlayer ID: <Interface: 0x1700ab2e0> 
sedPlayer: <MainViewController: 0x100406e30> 
Player ID: (null) 
viewDidLoad: <MainViewController: 0x100409550> 

Так что очевидно, что синглтон не работает как экземпляр MainViewcontroller отличается. Для singleton я использую стандартный метод dispatch_once, как и другие протоколы, которые работают нормально. ARC включается. Кто-нибудь знает, что здесь не так, и почему синглтон не работает?

+0

сначала вы должны использовать 'assign' заменить на' strong', когда вы используете 'delegate':' @property (сильный, неатомический) id player', во-вторых, разместите весь свой код в своем вопросе, мы можем найти, где проблема. – aircraft

+1

^Нет, используйте 'слабый' вместо' assign'. 'assign' потребует от вас« nil »ссылки на этот объект, когда он будет освобожден, или вы получите сбой при отправке сообщения на объект (теперь освобожденный). – AdamPro13

+0

@ Вы уверены, что '[MainViewController sharedInstance]' - это тот же экземпляр 'MainViewController', из которого вызывается' viewDidLoad'? – AdamPro13

ответ

0

Вот как я думаю, вы оказались с двумя экземплярами MainViewController. Первый, я полагаю, создается при навигации к экрану, связанному с MainViewController. Второй создается, когда вы вызываете [MainViewController sharedInstance] в Interface.m.

Как зрения ViewController лениво загружены («View контроллеры загрузить свои взгляды лениво. Доступ к свойству просмотра в первый раз нагрузках или создает виды контроллера представления.» Из Apple docs под ViewManagement), вы видите только журнал viewDidLoad: <MainViewController: 0x100409550> один раз, когда первый MainViewController получает навигацию и загружает представление.

Вот мое предложение:

Поскольку вы делаете Interface инициализации в - (void)viewDidLoad, вы можете также установить self.player = [Interface sharedInstance].

Код будет выглядеть примерно так:

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.player = [Interface sharedInstance]; 
    NSLog(@"Player ID: %@", _player); 
    NSLog(@"viewDidLoad: %@", self); 
} 

Вы также должны избавиться от - (void)sedPlayer:(id) pointer и + (instancetype)sharedInstance в вашем MainViewController. Никогда не рекомендуется иметь Singleton ViewController, так как вы можете в конечном итоге испортить навигацию или иметь несколько состояний.

Для более статей углубленного по избежанию одиночек, вы можете проверить objc.io Avoiding Singleton Abuse

+0

Кажется, я сделал это слишком сложно :) - Спасибо за вашу помощь !!! – Hecot

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