2

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メソッドに次を追加しようとしましたが、ステップスルーしても問題ありません。2番目のNSLogでクラッシュし、次のエラーが発生します。メッセージが割り当て解除されたインスタンス0x160d60に送信されました

-(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/

4

2 に答える 2

2

まず、メソッドはretrieveSettingsor downloadSettingsor である必要がありますが、接頭辞にはメソッドの引数に関して非常に特別な意味があるため (参照渡し)、そうでsettingsはありません。getSettingsget

第二に、そのコードには明らかな問題はありません( のリークを除けば、settingsこの種のクラッシュは発生しません)。(ARCが有効になっていることがわかります)。

最後に、クラッシュした場合は backtraceを投稿してください。表示されているエラー メッセージ ("USE_BLOCK_IN_FRAME") は、投稿したコードがクラッシュとは関係がないことを示しています。


奇妙なクラッシュ、それ。OK -- 警告はデバッガーからのもので、実際のエラーとは関係ありません。

多くの場合、スコープ境界は、コンパイラがrelease自動解放プールを発行および/または排出する場所です。

これは次の質問につながります。お元気ですか

これは、コードをステップ実行すると、デバイスで正常に動作するコードです。

OK -- つまり、全速力で実行すると機能せず、段階的に実行すると機能します。同時実行クラッシュのようなにおいがします。実際のクラッシュのスクリーンショットを投稿できますか? つまり、特定のバックトレースがクラッシュのバックトレースであり、クラッシュ時にデバッガーがたまたまあった場所ではないことを確信していますか?

(はい、ストローを少し握ります -- このクラッシュは、示されている証拠では意味がありません。私はパズルが好きです。)


わかりました - 今、私たちはどこかに到達しています。並べ替え。if のスコープ内で同じことを正常にログに記録した後、if のスコープでクラッシュします。

とはどのようにusername定義されていますか? それらは宣言ですか、それとも最も適切な宣言ですか?modulewebsiteURLstrongcopy @property

于 2012-04-17T16:38:24.787 に答える
0

NSZombieEnabled (または、シミュレーターで再現できる場合は、Instruments の Zombies 機能EXC_BAD_ACCESSを使用する時が来たと思います。

このスレッドには、タスクを達成する方法に関する指示があります。

于 2012-04-17T18:52:39.053 に答える