所以我遇到了循环依赖的问题,所以我试图实现前向声明。我有三个类(logger,api,helpers),所有这些都是单例对象。我有一个控制器类(globalclass),它具有链接到三个类的属性。
这是我的代码:
INCLUDES.H:
#import "globalclass.h"
#import "logger.h"
#import "api.h"
#import "helpers.h"
globalclass.h:
@class logger
@class api
@class helpers
@interface globalclass : NSObject
+ (id) sharedGlobal;
- (id) init;
...
@property (nonatomic, strong) logger *log;
@property (nonatomic, strong) api *remote;
@property (nonatmoic, strong) helpers *utils;
...
logger / api / helpers.h templates:
@class globalclass
@interface logger : NSObject
+ (id) sharedLogger;
- (id) init;
...
@property (nonatomic, strong) globalclass *gc;
...
globalclass.m:
#import "includes.h"
@implementation globalclass
/*
* Singleton Class
*/
+ (id) sharedGlobal
{
static globalclass *sharedGlobalClass = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedGlobalClass = [[self alloc] init];
});
return sharedGlobalClass;
}
/*
* Init
*/
- (id) init
{
self = [super init];
if (!self) return nil;
// Logging
self.logger = [logger sharedLogger];
...
return self;
}
logger / api / helpers.m模板:
#import "includes.h"
@implementation logger
/*
* Singleton Class
*/
+ (id) sharedLogger
{
static logger *sharedLog = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedLog = [[self alloc] init];
});
return sharedLog;
}
/*
* Init
*/
- (id) init
{
self = [super init];
if (!self) return nil;
// Global Class
self.gc = [GlobalClass sharedGlobal];
...
return self;
}
然后,在我的AppDelegate中,我有一个属性到全局类,我正在这样做:
self.gc = [GlobalClass sharedGlobal];
但是,似乎每次启动我的应用程序时,它都会停止并自动终止,因为启动时间太长。
我是否错误地考虑了前导全局?
该应用程序构建良好。
任何帮助都将不胜感激。
感谢。
答案 0 :(得分:3)
你有一个死锁,因为sharedGlobal
中的dispatch_once块是(通过全局类init)调用sharedLogger
,它本身正在调用sharedGlobal
(通过记录器类init)。
由于一切都是单身,因此您可以采取一些方法来避免此问题。这是两个:
一个。使用self.log
替换全局类中的所有[logger sharedLogger]
用法,并使用self.gc
替换记录器类中的所有[globalclass sharedGlobal]
用法。你可以完全摆脱这些属性。 dispatch_once
在第一次调用后非常快,因此性能不是将单例作为属性存储的原因(尽管您可以想象有其他原因)
B中。保留log
和gc
属性,但使用自定义getter将它们设为只读属性:
@property (nonatomic, readonly) globalclass *gc;
// implementation:
- (globalclass *)gc
{
return [globalclass sharedGlobal];
}
@property (nonatomic, readonly) logger *log;
// implementation:
- (logger *)log
{
return [logger sharedLogger];
}
我个人会选择A.
这两种替代方法都消除了对init方法中单例访问器的任何引用,从而消除了死锁。