Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/111.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 转发声明暂停应用程序_Ios_Objective C_Xcode - Fatal编程技术网

Ios 转发声明暂停应用程序

Ios 转发声明暂停应用程序,ios,objective-c,xcode,Ios,Objective C,Xcode,所以我遇到了循环依赖的问题,所以我试图实现前向声明。我有三个类(logger、api、helpers),它们都是单例对象。我有一个控制器类(globalclass),它的属性链接到这三个类 这是我的密码: 包括.h: #import "globalclass.h" #import "logger.h" #import "api.h" #import "helpers.h" globalclass.h: @class logger @class api @class helpers @inte

所以我遇到了循环依赖的问题,所以我试图实现前向声明。我有三个类(logger、api、helpers),它们都是单例对象。我有一个控制器类(globalclass),它的属性链接到这三个类

这是我的密码:

包括.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模板:

@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]

然而,似乎每次我启动我的应用程序时,它都会暂停并自动终止,因为启动时间太长

我是不是在错误地考虑远期球

该应用程序构建良好

任何帮助都将不胜感激


谢谢。

您遇到了死锁,因为
sharedGlobal
中的dispatch_once块(通过全局类init)正在调用
sharedLogger
,而它本身正在调用
sharedGlobal
(通过记录器类init)

因为一切都是单例的,所以有几种方法可以避免这个问题。这里有两个:

A.将全局类中的任何
self.log
用法替换为
[logger sharedLogger]
,并将logger类中的任何
self.gc
用法替换为
[globalclass sharedGlobal]
。您可以完全删除这些属性
dispatch_once
在第一次调用后速度非常快,因此性能不是将对单例的引用存储为属性的原因(尽管您可能有其他原因)

B.保留
日志
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方法中消除了对单例访问器的任何引用,从而消除了死锁。

乍一看,我认为您遇到了死锁。是的,通过一些调试,我认为globalclass无法完成其初始化,因为当它开始初始化记录器时,它包含一个globalclass init并继续这个循环。另外,我想问,是否有一个很好的理由让所有这些类都是单例的?例如,一个单例对象“拥有”另一个类的实例,而另一个类不再是单例对象,这可能更有意义。或者,您可以将其中一个单例类分解为更细粒度的职责集,并将其代码分发给其他类。或者使用类别。等