2011-01-07 9 views
0

私はUITableViewControllerを持っていますが、メソッドがWebデータを読み込めなかった場合、テーブルビュー上にエラーメッセージをオーバーレイするために使用されるUIView *はerrorViewと呼ばれます。奇妙な!=なしチェックの問題

initメソッドでは、errorViewはnil(デバッガの0x0)に設定されています。

ロードメソッドで、initの最後に呼び出され、 'refresh' UIButton(errorView上)がタップされている場合、errorViewはnilと比較され、superviewから削除され、デバッガでは0x0)。

deallocメソッドでは、解放前に同じチェックが行われます。何らかの理由で、データが失敗したメソッドが呼び出されなかったため、変数が割り当てられていなくても(デバッガの0xc000)、変数は決してゼロにはなりません。それから、アプリケーションは!= nilのヌルポインタをdeallocしようとするためクラッシュします。

例:

-(id)init { 
    errorView = nil; 
    [self Load]; 
} 

-(void)Load { 
    if(errorView != nil) { 
     [errorView removeFromSuperView]; 
     [errorView release]; 
     errorView = nil; 
    } 

    //Attempt to load data from web 
} 

-(void)dataFailedToLoad (e.g. UIWebView didFailLoadWithError) { 
    errorView = [[UIView alloc] initWithFrame, etc]; 
    [self.tableView addSubview:errorView]; 
} 

-(void)dealloc { 
    if(errorView != nil) 
     [errorView release]; //Always crashes because errorView is never nil even though it has been assigned nil? 
} 

私はこの上の髪を引っ張っています。 errorView変数は、説明されているようにこれらのメソッド以外の場所では使用されません。読み込むことができるのは、それを行う適切な方法であることが示唆されています。

+0

これは実際のコードですか、それとも最小限のサンプルですか? init()とdealloc()メソッドで、((self = [super init]))と[super dealloc]が呼び出されていない場合、... –

+0

は 'errorView'自体に問題がない可能性があります。あなたは 'UITableViewController'を2回(あるいはあなたが想定している以上に)解放しているかもしれませんか?そのため、 'errorView'変数にガベージを持つ可能性のある無効な' UITableViewController'オブジェクトに対して 'dealloc'メソッドが呼び出されます。 – filipe

+0

これは非常にうまく取り除かれたバージョンであり、はい、元のルーチンに言及しています。 UITableViewControllerは、View Controllerがポップされると自動的に解放されます。 (親ビューコントローラを作成してプッシュした後で) –

答えて

3

nilオブジェクトにメッセージを送信することはエラーではありません。かなりの数の小切手が完全に無用です。

ここで行われていることは、詳細な情報がないと指摘するのは難しいです。 dataFailedToLoad 実際にがerrorViewが割り当てられている唯一の場所であれば、コードは機能するはずです。しかし、それは何か他の人があなたのおしゃぶりを犯していることを示しています。

なお、!= nilのヌルポインタはヌルポインタではありません。

+0

を使用します。オブジェクトが割り当て解除されているかどうかを安全に確認する唯一の方法は、解放するたびに(または即時に割り当てられない場合)そして、errorViewは他のどこにもアクセスされていません。 errorView機能を追加した後に問題が発生しました。 –

+0

最も近い答え。問題は、[super dealloc]を最初に呼び出すことであり、最後には--all void(dealloc)と呼ばれていたことが判明しました。 –

+0

@Toby Wilson:そのため、「圧縮された」コードサンプルを投稿することは悪い考えです。 –

1

initと呼んだだけで、ビューを初期化する必要はありません。ビューがゼロでないことを確認するには、標準メソッドviewDidLoadを使用する必要があります。

+0

私が与えた例は単純化されています。実際のバージョンでは、if(self = [super initWithStyle:]) –

0

あなたが話していると思うインスタンスと話していますか?

インターフェイスファイル(xib)の読み込みと開発者のインスタンス化の間に混乱が生まれています。

I.e.すべての方法でNSLog(@"%@ %p", self, self);のようなことをして、アドレス - インスタンス - が同じであることを確認してください。