【问题标题】:iPhone Simulator Hangs on NSLogiPhone模拟器挂在NSLog上
【发布时间】:2014-04-25 12:09:14
【问题描述】:

我在这里遇到了一个奇怪的问题。我正在 Sprite Kit 中创建一个游戏,当我第一次初始化所有变量时,它似乎工作正常。我有一个单例类,其中包含我将在游戏中使用的所有数据。这个单例包含一个对象(世界),世界对象包含我在整个游戏中使用的对象数组。

初始化后,我尝试打印出 Wo​​rld 对象包含在某个数组中的内容。下面是一个例子:

NSLog(@"Game manager ports: %@", [IPGameManager sharedGameData].world.ports);

但是,当它运行时,模拟器会挂起。我还没有在真实设备上尝试过(还没有开发者帐户)。但是,当我在 World 'ports' 初始化后立即打印相同的内容时,它打印得很好。这是 World 对象的头文件:

@interface IPWorld : NSObject <NSCoding>

@property (nonatomic, retain) IPPlayer* player;
@property (nonatomic, retain) NSMutableArray* ports;
@property (nonatomic, retain) NSMutableArray* crewMembers;
@property (nonatomic, retain) NSMutableArray* ships;
@property (nonatomic, retain) NSMutableArray* quests;

@end

我认为“保留”或其他任何事情都不会导致这种情况,但我不确定问题是什么。任何帮助是极大的赞赏。谢谢!

编辑:: 下面是我的单例代码:

+(instancetype)sharedGameData {
    NSLog(@"Loading sharedGameData");
    static id sharedInstance = nil;

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSLog(@"should only see this once");
        sharedInstance = [self loadInstance];
    });

    return sharedInstance;
 }

+(instancetype)loadInstance {
    NSData* decodeData = [NSData dataWithContentsOfFile:[IPGameManager filePath]];
    if (decodeData) {
        IPGameManager* gameData = [NSKeyedUnarchiver unarchiveObjectWithData:decodeData];
        return gameData;
    }
    return [[IPGameManager alloc] init];
}

+(NSString*)filePath {
    static NSString* filePath = nil;
    if (!filePath) {
        filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:@"gamedata"];
    }
    return filePath;
}

【问题讨论】:

  • 请发布崩溃消息
  • 没有崩溃。它只是挂起。
  • 您的-[IPGameManager init] 方法中有什么有趣的东西(即除了简单的实例变量赋值之外)吗?
  • [IPGameMamager init] 函数所做的就是self.world = [[IPWorld alloc] init];。但在 [IPWorld init] 函数中,它设置了“世界”,就像创建港口、船员、船只等数组一样。
  • 我想在初始化 IPGameManager 单例时初始化我的播放器对象(它是世界对象的一部分)。一些端口是IPPlayer 对象的一部分,但我必须在初始化期间从单例访问这些端口。这甚至可能吗?

标签: ios objective-c singleton ios-simulator


【解决方案1】:

要调试任何挂起,您首先需要的是所有线程的堆栈跟踪。在 iOS 模拟器中发生这种情况时,按下 Xcode 中的“暂停”按钮并查看堆栈跟踪。您还可以在调试器窗口中输入t a a bt(表示线程应用所有回溯)来转储所有线程的堆栈跟踪。

一旦你有了它,看看你的主线程被阻塞了什么(例如,死锁、阻塞 i/o、无限递归)。

【讨论】:

  • sharedGameData 通话肯定会停止,但我不知道为什么。我相信我已经正确实现了 dispatch_once 代码。我会用代码更新主题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-24
  • 2023-04-01
  • 1970-01-01
  • 2011-01-04
  • 2011-05-08
  • 1970-01-01
  • 2010-10-06
相关资源
最近更新 更多