2009-07-06 17 views
3

キーボードの戻るボタンを押すと、メソッドが呼び出されます。整数を返す別のメソッドを呼び出した後、その整数に基づいてメッセージが作成されます。メッセージはUIAlterViewに渡され、ユーザーに表示されます。アラートにはオプションがありません(なぜ私は代理人を呼び出さないのですか)。しかし、単に何が起こったのかをユーザーに通知します。UIAlertViewが表示されず、 "EXC_BAD_ACCESS"エラーが発生しない

編集:以下は完全な方法です(以前は部分的に表示されていました)。 UIAlertViewの前にすべてをコメントアウトし、メッセージを渡す代わりに文字列@ "test"を代用すると、警告が正常に表示されます。私の構造で正しくメモリを扱っていませんか?

- (IBAction)joinButton { 
    struct userInfo localUser; 

    [emailAddress resignFirstResponder]; 

    //convert textField text to char array in structure 
    localUser.firstName = [self convertStringtoCharArray:firstName.text]; 
    localUser.lastName = [self convertStringtoCharArray:lastName.text]; 
    localUser.username = [self convertStringtoCharArray:username.text]; 
    localUser.email = [self convertStringtoCharArray:emailAddress.text]; 
    localUser.ipAddress = [self convertStringtoCharArray:localIPAddress.text]; 
    localUser.latitude = currentLocation.coordinate.latitude; 
    localUser.longitude = currentLocation.coordinate.longitude; 

    //pass structure to be sent over socket 
    int result = [myNetworkConnection registerWithServer:&localUser]; 

    NSString *message = nil; 

    //process result of sending attempt 
    if (result == 0) { 
     //registration succesful 
     message = [NSString stringWithString:@"Registration successful"]; 
    } else if (result == 1) { 
     //server unavailable 
     message = [NSString stringWithString:@"Server unavailable. Please check your wi-fi settings and try again."]; 
    } else if (result == 2) { 
     //unable to establish connection 
     message = [NSString stringWithString:@"Unable to communicate with server. Please check your wi-fi settings and try again."]; 
    } else if (result == 3) { 
     //username already in use 
     message = [NSString stringWithString:@"Username in use. Try another username."]; 
    } 

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Registration" 
                message:message 
                delegate:nil 
              cancelButtonTitle:@"Ok" 
              otherButtonTitles:nil]; 

    [alert show]; 
    [alert release]; 
} 

私がコードを実行すると、iPhoneは警告を表示しようとしているのにクラッシュするようになります。コンソールにEXC_BAD_ACCESSエラーが表示されます。アラートまたはメッセージを正しくリリースしていませんか?ここでは、コンソール出力は次のようになります。

Program received signal: “EXC_BAD_ACCESS”. 
(gdb) backtrace 
#0 0x30011944 in objc_msgSend() 
#1 0x3054803e in NSPopAutoreleasePool() 
#2 0x3054c808 in -[NSAutoreleasePool release]() 
#3 0x30936ac4 in _UIApplicationHandleEvent() 
#4 0x3204696c in PurpleEventCallback() 
#5 0x30254a76 in CFRunLoopRunSpecific() 
#6 0x3025416a in CFRunLoopRunInMode() 
#7 0x320452a4 in GSEventRunModal() 
#8 0x308f037c in -[UIApplication _run]() 
#9 0x308eea94 in UIApplicationMain() 
#10 0x000020bc in main (argc=1, argv=0x2ffff508) at /Users/reu2009/Documents/iPhone Development/Development/BuddyTracker/main.m:14 
(gdb) frame 10 
#10 0x000020bc in main (argc=1, argv=0x2ffff508) at /Users/reu2009/Documents/iPhone Development/Development/BuddyTracker/main.m:14 14  int retVal = UIApplicationMain(argc, argv, nil, nil); 

編集:[message release];を取り除き、回答に基づいて[NSString stringWithString];を使用して文字列を割り当てます。

+0

メッセージをメッセージに置き換えると動作しますか?@ "test"? –

+0

同じエラーです。私は条件付きメッセージ作成ブロックをコメントアウトしました。 –

+0

非常に奇妙です。エラーが発生した行を特定するために、デバッガをステップアップしてみましたか?私たちが間違った場所を探しているのであれば、私はちょっと不思議です。 –

答えて

4

便利なコンストラクタから返されるオブジェクトは、すでにautoreleaseに設定されています。 "message"へのポインタを宣言している間は、NSStringオブジェクトを作成するために@ "string"コンストラクタを使用しているので、 "message"オブジェクト自体はあなたのものではありません。したがって、あなたはそれを解放する必要はありません。

これを手動でリリースすると、リリースされる回数が手動で1回、自動解放処理が1回実行されてから何度もリリースされ、エラーがスローされます。親指の

http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html

良いルール:ここ

は、Appleからのいくつかの追加情報がありますあなたがオブジェクト(またはオブジェクトを自分で保持している場合)を作成するためのallocまたはinitまたはコピーのいずれかの方法を使用しない限り、それを解放する必要はありませんが、実際にそれを作成した方法に依存することができます。

+0

ありがとうございます。ただし、[メッセージの解放]を削除した後。私は同じエラーが発生します。それはメッセージ文字列の解放を超えた何かでなければなりません。 –

+0

さて、私は当惑しています。 :)私はケンの提案を試し、おそらく "int result ..."という行をコメントアウトして、それらのどれかが問題に影響を与えるかどうかを見ていきます。 –

+0

私はルールがalloc、retainまたはcopyを含むメソッドであると信じています。オブジェクトを解放する必要があります。 – Mark

0

Seanが正しいです - メッセージオブジェクトを実際には保持していないので、ここで[message release]を呼び出す必要はありません。

message = @"string"というだけでなく、message = [NSString stringWithString:@"string"];と言う必要があります。私はなぜ(誰かがコメントすることができ、私はこの投稿を改善することができます!)しかし、それはトリックを行う必要があります。

+1

私はこれらの文字列が同じ正確なことを行うことは間違いないと確信しています... '' string ''と' [NSString stringWithString:@ "string"] 'はどちらも非保持NSStringを返します。 – davidcann

1

NSZombieEnabled = YESで試してみてください。

  • 実行可能な情報に移動します。
  • [引数]タブをクリックします。
  • 「環境変数に設定する」をクリックします。
  • NSZombieEnableとYESを入力します。

すでにリリースされているメモリが解放されると、NSZombieはそのアドレスを表示し、Instrumentsを使用して実際のオブジェクトを見つけることができます。コービンのツリーハウスには、これを行う方法の良い概要を説明しています Instruments on Leopard: How to debug those random crashes in your Cocoa app

0

私はUIAlertViewとここに同じ問題を抱えていた、私の場合、私は警告を実装する別のクラスを持っていた、そして、私は静的を呼んでいた別の1から方法。次のように:私は疑う

ClassA 

... 

doSomething { 
... some stuff ... 

[MyAlertView showAlert]; 

... some other stuff... 

} 

私はオブジェクトがすでにリリースされたボタンをクリックしたときにalertviewが非同期的に示されているように、ということです。

これを確認するために、アラートをインスタンス化してリリースしないようにコードを変更しました。そして、いつも働いていた。

私の最終的な解決策は、親ビューで変数を宣言し、ビューが割り当て解除されたときに他の変数との割り当てを解除することでした。

8

私はこのような問題を持っていた...私はメインスレッドから

+0

これはまさに私の問題でした。ありがとう。 – a1phanumeric

+0

j2emanueの意味の例は、http://stackoverflow.com/questions/12468677/exc-bad-access-code-2-on-uialertview-in-ios6を参照してください。 –

0

それを呼び出す....バックグラウンドスレッドからuiAlertViewを呼んでいたこれは、バックグラウンドスレッド

Iからの更新のUIKitにケースでしたこのように解決しました

UIAlertView *alertMSG = [[UIAlertView alloc] initWithTitle:nil 
         message:@"Your mnessage here" 
         delegate:self 
         cancelButtonTitle:@"Title here" 
         otherButtonTitles: nil]; 

    [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 
     [alertMSG show]; 
    }]; 
関連する問題