【发布时间】:2016-12-19 16:05:07
【问题描述】:
我对 obj-c 很陌生,目前正在修改一些现有代码,其中使用了很多导致随机崩溃的单例。我设法用适当的协议替换了其中的大多数,但仍然难以在 ONE 代表上设置参考。我在这里读过一些关于单例和协议的帖子,也提到了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.编辑 ///
有人问我关于单例的初始化 - 在我的 MainViewController.m 中,第一次实例化 PlayerInterface 对象:
- (void)viewDidLoad {
self.player = [PlayerInterface sharedInstance];
}
我也试图避免 dispatch_once:
- (void)viewDidLoad {
PlayerInterface *play = [[PlayerInterface alloc] init];
self.player = play;
}
但没什么区别......也会崩溃!谁能帮忙?
/// 2.编辑 ///
我尝试了一个奇怪的解决方法:当我第一次实例化 PlayerInterface 时,我将 ID 设为全局变量(我知道这与面向对象编程的想法背道而驰)。
extern id play;
当涉及到委托时,我现在可以使用以下方法轻松设置引用:
self.delegate = play;
它就像一个魅力,只是很好的旧 C 风格:)
我认为单例的问题是基于我有三个相互通信的对象这一事实。我会将通信重新路由到“星型”,看看这是否有帮助。
【问题讨论】:
-
1) 崩溃的错误是什么? 2) 代表和单例之间没有任何关系。它们是两个完全独立且独立的概念。 3) 你为什么使用
@synthesize?不要遵循任何使用@synthesize的过时教程(在大多数情况下)。 -
+1 表示不使用合成。您提供的代码没有崩溃。
PlayerInterface对象的初始化可能有问题。 -
+1 用于崩溃日志。如果不了解更多关于崩溃本身的信息,我们可以提供的建议很少。正如@CharlesThierry 上面所说,您在上面发布的代码实际上并没有显示任何潜在的崩溃,所以它看起来在其他地方。但作为说明;单例的使用应该是有限的,很多时候它们引起的问题多于它们的价值,所以要小心。
-
请同时设置异常断点,并分享崩溃源。
-
问题出在
dispatch_once调用内部。使用单身人士的init方法更新您的问题。确保init方法不会直接或间接导致对sharedInstance方法的任何访问。
标签: ios objective-c reference delegates singleton