iOS - 使用单例

时间:2016-12-19 16:05:08

标签: ios objective-c reference delegates singleton

我对obj-c很新,并且正在重新编写一些现有代码,其中使用了大量单例导致随机崩溃。我设法用适当的协议替换它们中的大部分,但仍然很难在一个代表上设置引用。我在这里阅读了一些关于单身人士和协议的帖子,并且还提到了apple docs,但是我读的越多,我就越困惑。我认为有一个我不知道的副作用 - 有人可以帮助理解。

我需要设置委托引用是PlayerInterface实例的ID(指针地址)。

这是我到目前为止所做的:

// define delegate in DocumentsViewController.h
@property (weak, nonatomic) id <documentsProtocol> delegate;

// in DocumentsViewController.m
// set delegate reference using singleton
self.delegate = [PlayerInterface sharedInstance]; // here it crashes!

这是我遇到的当前问题,当我通过单例设置委托引用时,它会在线程上崩溃。 ARC功能已开启!

crash-log

对于我正在使用的单身人士:

// in PlayerInterface.m (NSObject)
+ (instancetype)sharedInstance
{
    static dispatch_once_t once;
    static id sharedInstance;
    dispatch_once(&once, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}

/// 1.EDIT ///

我被问到单例的初始化 - 在我的MainViewController.m中,第一次实例化PlayerInterface对象:

- (void)viewDidLoad {
    self.player = [PlayerInterface sharedInstance];
}

我也试图避开dispatch_once:

- (void)viewDidLoad {
    PlayerInterface *play = [[PlayerInterface alloc] init];
    self.player = play;
}

但没有任何区别......也崩溃了!有谁可以提供帮助?

/// 2.EDIT ///

我尝试了一种奇怪的解决方法:当我第一次将ID设置为全局变量时实例化PlayerInterface(我知道这违反了面向对象编程的想法)。

extern id play;

说到授权,我现在可以使用以下方法轻松设置引用:

self.delegate = play;

它就像一个魅力,只是很好的旧C风格:)

我认为单例的问题是基于这样一个事实,即我有三个相互通信的对象。我将把通信重新路由到“星型”,看看这是否有帮助。

2 个答案:

答案 0 :(得分:0)

委托只是一个可以查询ID和其他任何属性的对象,就像任何其他对象一样。添加到您的&#34; documentsProtocol&#34; a&#34; tellMeYourID&#34;方法和你的业务。

答案 1 :(得分:0)

我有三个通过协议相互通信的对象。即使我注意不要以委托循环结束,这似乎导致了这个问题。将通信重新路由到“星型”后#34;所有问题都消失了。现在每个对象只是与另一个对象进行通信。 MainViewController是中间的主人,如果我需要传递信息,我添加了一个简短的方法,如:

// passing through MainVC to keep star type communication
- (void)updateList:(NSArray)list { 
    [self.player setList:list];
}

我不知道这是否是完美的解决方案,但比使用保存播放器实例ID的全局变量要好得多:)