我对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功能已开启!
对于我正在使用的单身人士:
// 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风格:)
我认为单例的问题是基于这样一个事实,即我有三个相互通信的对象。我将把通信重新路由到“星型”,看看这是否有帮助。
答案 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的全局变量要好得多:)