2012-01-13 18 views
2

私は、ユーザにIPアドレスの入力を促すために、UIAlertViewを拡張するレガシーC#クラスを持っています。また、IPアドレスを保持し、デフォルトのエントリ値としてロードします。UIAlertViewでMonoTouchランタイムがクラッシュする理由を教えてください。

元のコードはiOS4.x UIAlertViewをハッキングしてテキストフィールドを追加しましたが、レイアウト上の問題がいくつかありました。私はiOS5 UIAlertViewAlertViewStyleの設定を使用するようにコードを変換し、すべて正常に機能しました。

私はそれが接続ボタンへのショートカットことができるように、ポップアップキーボードの完了キーを有効にするように頼まれました。クラスのコンストラクタに次のように私は、コードを追加しました:

public AddressAlertView() 
{ 
    AddButton("Cancel"); 
    AddButton("Connect"); 
    AlertViewStyle = UIAlertViewStyle.PlainTextInput; 

    // NEW - get input text field, enable Done on the keyboard and 
    // allow Done to be the same as the Connect button 
    UITextField fld = GetTextField(0); 
    fld.ReturnKeyType = UIReturnKeyType.Done; 
    fld.ShouldReturn = (textField) => 
    { 
     DismissWithClickedButtonIndex(1, true); 
     return textField.ResignFirstResponder(); 
    }; 
    // *** end of new code *** 

    // restore saved IP address 
    string savedAddress = NSUserDefault.StandardUserDefaults.StringForKey(AddressKey); 
    if (savedAddress != null) 
     fld.Text = savedAddress; 
} 

クラスがそうのように使用されます:今

.... 
AddressAlertView addrPrompt = new AddressAlertView(); 
addrPrompt.Title = "IP Address"; 
addrPrompt.Message = "Enter address"; 
addrPrompt.Dismissed += (sender, e) => 
{ 
    if (e.ButtonIndex == 1) 
    { 
     // use IP address... 
     .... 
    } 
}; 
addrPrompt.Show(); 
.... 

問題。このコードを実行すると、AddressAlertViewはポップアップダイアログを正しく表示し、すべてが以前と同じように機能します。しかし、私がをタップした場合、キーボードでを完了すると、アプリはUIAlertViewに爆発します。

新しいコードをpublic override void LayoutSubviews()メソッドに移動しようとしましたが、それでもクラッシュします。

アイデア?あなたはクラスのメンバとしてAddressAlertViewを宣言する必要が

+0

申し訳ありませんが、まだコメントの書式を学習しています。理解した。 MonoTouchのトレースダンプの出力を見ると、無効なオブジェクトが記述されていました。テキストフィールドをローカル変数として取得する代わりに、インスタンス変数として参照を保存します。 'private UITextField _addressTextField = null;'コンストラクタのコードを '_addressTextField = GetTextField(0);'に変更しました。それはクラッシュを解決した。ローカルの 'UITextField'変数は間違いなくGC'dになり、' ShouldReturn'ラムダ式が呼び出されたときにクラッシュしました。 – hypercode

+0

類似の問題の解決策を探している人を助けるために、あなたの説明を解答し、自分の答えを受け入れるべきです。これは完全に大丈夫であり、StackOverflowで欲しいです。 – Krumelur

答えて

1

AddressAlertView addrPrompt; 
public void DoSomething() 
{ 

    addrPrompt = new AddressAlertView(); 
    //etc 

} 

状況のこの種の問題(私はUIAlertViewsと同様の多くを持っていた)AddressAlertViewオブジェクトがGC'dされていることで、イベントハンドラクラッシュを引き起こします。これが問題であることを確認するには、何も変更しないでください。addrPrompt.Dismissed += ...行を削除/コメントしてもう一度テストしてください。クラッシュしない場合、これが解決策です。

+1

ええ、私は似たようなものを発見しました。上記の私のコメントを参照してください。私は 'AddressAlertView'をクラスメンバにする必要はありませんでした。 – hypercode

+0

UIAlertViewは、Monotouchがスマートを処理するクラスの1つです。あなたはクラス参照を保持する必要はありません。 MTはこれを内部的に処理します。 – Krumelur

+0

@Krumelurこれは確かですか?私は数ヶ月前にUIAlertViewに関する多くの問題を抱えていました。これを述べたので、私は最新の安定版をもう一度チェックします。 –

0

は、Appleのドキュメントによると、あなたはUIAlertViewをサブクラス化するべきではありません。

http://developer.apple.com/library/ios/#documentation/uikit/reference/UIAlertView_Class/UIAlertView/UIAlertView.html

+0

うん、私はこの問題でAppleのセイジ語を知っている。私はこのコードを継承したので、それを機能させる必要がありました。このクラスを行うより良い方法は、それを継承するのではなく、 'UIAlertView'をカプセル化することです。いろいろなMonoTouch岩石の仕事。 – hypercode

0

はそれを考え出しました。 MonoTouchのトレースダンプの出力を見ると、無効なオブジェクトが記述されていました。代わりに、ローカル変数としてテキストフィールドを取得し、私はインスタンス変数として、それへの参照を保存します。

_addressTextField = GetTextField(0); 

出来上がり:

private UITextField _addressTextField = null; 

は私がにコンストラクタでコードを変更しました!それはクラッシュを解決した。ローカルのUITextField変数は間違いなくGC'dを取得しており、ShouldReturnラムダ式が呼び出されたときにクラッシュしました。

関連する問題