【问题标题】:iOS5 BAD_EXCESS only on deviceiOS5 BAD_EXCESS 仅在设备上
【发布时间】:2012-04-29 00:15:15
【问题描述】:

我正在运行一个后台线程来从 Web 服务获取数据。

要获得创建 URL 所需的设置,我使用此方法:

+(Settings *)getSettings
{
    Settings *settings = [[Settings alloc] init];
    NSString *path = [NSString stringWithFormat:@"Documents/Settings"];
    NSString *settingsPath = [NSHomeDirectory() stringByAppendingPathComponent:path];
    NSFileManager *fileMgr = [NSFileManager defaultManager];
    if ([fileMgr fileExistsAtPath:settingsPath]) {
        NSDictionary *settingsDictionary = [NSDictionary dictionaryWithContentsOfFile:settingsPath];
        settings.username = [settingsDictionary objectForKey:@"username"];
        settings.module = [settingsDictionary objectForKey:@"module"];
        settings.websiteUrl = [settingsDictionary objectForKey:@"websiteUrl"];

    }else
    {
        settings.username =  @"";
        settings.module =  @"";
        settings.websiteUrl =  @"";
    }
    NSLog(@"Settings = u:%@ m:%@ w:%@",settings.username,settings.module,settings.websiteUrl);
    return settings;
}

这在调试器中运行良好,但是当我在设备上运行它时,我在 NSLog 或任何尝试使用带有警告的数据的类上得到 BAD_EXCESS:

警告:尝试使用不在框架中的块创建 USE_BLOCK_IN_FRAME 变量。

如果我单步执行代码,这就是代码在设备上可以正常工作。

有什么想法吗?

编辑: 回溯 -

#0  0x37a97eda in objc_retain ()
#1  0x37aa4be4 in objc_retainAutoreleasedReturnValue ()
#2  0x0000f84a in +[SettingData getSettings] (self=0x175e4, _cmd=0x11af9) at /Users/Jono/Dropbox/Uni/iOS5/Feedback At Tees/Feedback At Tees/SettingData.m:49
#3  0x0000fa86 in -[DataManager init] (self=0x3509e0, _cmd=0x30fd9f96) at /Users/Jono/Dropbox/Uni/iOS5/Feedback At Tees/Feedback At Tees/DataManager.m:19
#4  0x00003b46 in __35-[MasterViewController viewDidLoad]_block_invoke_0 (.block_descriptor=0x185f40) at /Users/Jono/Dropbox/Uni/iOS5/Feedback At Tees/Feedback At Tees/MasterViewController.m:70
#5  0x30b08d54 in _dispatch_call_block_and_release ()
#6  0x30b0b896 in _dispatch_worker_thread2 ()
#7  0x37a0e1ce in _pthread_wqthread ()
#8  0x37a0e0a4 in start_wqthread ()

我尝试将以下内容添加到设置的 init 方法中,如果我单步执行它是可以的

-(id)init
{
    if ((self=[super init]))
    {
        NSString *path = [NSString stringWithFormat:@"Documents/Settings"];
        NSString *settingsPath = [NSHomeDirectory() stringByAppendingPathComponent:path];
        NSFileManager *fileMgr = [NSFileManager defaultManager];
        if ([fileMgr fileExistsAtPath:settingsPath]) 
        {
            NSDictionary *settingsDictionary = [NSDictionary dictionaryWithContentsOfFile:settingsPath];
            self.username = [settingsDictionary objectForKey:@"username"];
            self.module = [settingsDictionary objectForKey:@"module"];
            self.websiteUrl = [settingsDictionary objectForKey:@"websiteUrl"];
            NSLog(@"Settings = u:%@ m:%@ w:%@",self.username,self.module,self.websiteUrl);
        }
        else
        {
            self.username =  @"";
            self.module =  @"";
            self.websiteUrl =  @"";
        }
    }
    NSLog(@"Settings = u:%@ m:%@ w:%@",self.username,self.module,self.websiteUrl);
    return self;
}

截图: http://postimage.org/image/4vw6uq7pp/

【问题讨论】:

  • BAD_EXCESS 还是 EXC_BAD_ACCESS?
  • 刚刚检查是 EXC_BAD_ACCESS
  • 未使用分析仪,不知道如何使用它找到它,我正在使用 arc yes
  • 可能想试试下面的 (stackoverflow.com/questions/3637714/…) NSString* string = [[NSString alloc] initWithUTF8String:line];
  • BAD_EXCESS 错误是过度放纵的典型症状

标签: iphone objective-c ios ipad


【解决方案1】:

首先,方法应该是retrieveSettingsdownloadSettings,或者,只是settings,但不是getSettings,因为get作为前缀对于方法的论证有非常特殊的意义(通过参考)。

其次,该代码并没有明显的问题(除了settings的泄漏,但这不会导致这种崩溃)。 (我看到 ARC 已启用)。

最后,如果您发生了崩溃,那么发布回溯。您看到的错误消息(“USE_BLOCK_IN_FRAME”)表明您发布的代码与崩溃无关。


奇怪的崩溃,那个。好的——警告来自调试器,与实际错误没有任何关系。

范围边界通常是编译器发出release 和/或耗尽自动释放池的位置。

这会引出下一个问题;怎么样

如果我单步执行代码,这就是代码在设备上可以正常工作。

好的——所以,当你全速运行时它不起作用,而在逐步运行时它起作用。闻起来像并发崩溃。你能发布实际崩溃的截图吗? IE。您确定特定的回溯是崩溃的回溯,而不是调试器在崩溃时发生的位置吗?

(是的,稍微抓紧了救命稻草——根据所显示的证据,这次崩溃没有意义。我喜欢谜题。)


好的——现在我们已经到了某个地方。有点。在成功记录相同的东西inside if 的作用域后,它会在 if 的作用域 outside 崩溃。

usernamemodulewebsiteURL 是如何定义的?它们是 strong 还是最恰当的 copy @property 声明?

【讨论】:

  • 添加了我认为是我的主要问题的回溯
  • 问题似乎是,无论我在哪里实例化设置或尝试在上面的方法中设置值,它都会被释放,但是当我放入其中一个 cmets 时,我正在使用 ARC。我使用 NSZombieEnabled 并得到 [CFString retain]: message sent to deallocated instance 任何我尝试使用设置值的地方。
  • 首先,重命名方法,因为这很麻烦。其次,显示调用settings 方法的东西。最后,贴出那张截图——很难想象粘贴的回溯是如何导致崩溃的。
  • 在我的主要帖子的方法中使用 NSLog,它甚至没有退出 init 方法
  • 完成!这是因为它们是在我的设置类中分配的,将属性更改为复制并且所有工作!将不得不阅读,因为我不明白其中的区别。我现在可以睡觉了哈哈,非常感谢!
【解决方案2】:

当我看到 EXC_BAD_ACCESS 时,我认为是时候使用 NSZombieEnabled(如果您可以在模拟器上重新生成它,也可以使用 Instruments 中的 Zombies 功能。

This thread 有关于如何完成任务的说明。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-07
    相关资源
    最近更新 更多