2011-10-25 1 views
3

テーブルビューの各UITableViewCell(2つのセルを除く)に追加されるUIButtonがあります。 ボタンのターゲットはUITableViewControllerです。 私は、アクションが間違ったターゲットに送信されたときにアプリケーションがクラッシュしたことに気付きました。私は、これは、ターゲットが何らかの方法で割り当て解除されたためだと仮定しています(たとえ、UITableViewControllerの割り当てが解除されていても、ボタンが表示されず、押されてはいけません。UIButtonのターゲットアクションの削除

私は、addTargetメソッドとremoveTargetのバランスをとる必要があると思います。 KVOのように、保持/解放する。

しかし、ボタンを作成してセルに追加したときのボタンへの参照しかないので、どこでこれを行うのかはわかりません。cellForRowAtIndexPath:?あなたはこのためにUIButtonをサブクラス化しているか、あなたは、細胞やボタンの割り当てが解除されたときにボタンのターゲットアクションを削除するには、そこにコードを置くことができるのUITableViewCellをサブクラス化している場合は

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    static NSString *CellIdentifier = @"Cell"; 

    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease]; 
     UIButton *extraButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
     [extraButton setFrame:CGRectMake(0, 0, 60, 30)]; 
     [extraButton setTitle:@"Meta" forState:UIControlStateNormal]; 
     [extraButton addTarget:self action:@selector(extraButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; 
     cell.accessoryView = extraButton; 
    } 

    if (indexPath.row == kNoExtraButtonRow) { 
     cell.accessoryView.hidden = YES; 
    } else { 
     cell.accessoryView.hidden = NO; 
    } 
    //set textlabels etc... 
    return cell; 
} 

答えて

0

。 UITableViewCellのdeallocでは、ボタンのremoveTargetを呼び出すことも、ボタンのdeallocでremoveTargetを呼び出すこともできます。

3

これは非常に珍しいことです。他の方法でメモリを誤って管理している可能性があります。特に、UIButtonのターゲットは、そのボタンを所有するUIViewControllerである必要があります。ほとんどの良いデザインでは、ボタンは常にコントローラよりも寿命が短くなっています。 UIButtonは他の場所に保持していますか? nibファイルを使用してボタンを管理しているのですか、それともプログラムで生成していますか? UIエレメントがプログラムで作成されたときに、複数のUIエレメントのインスタンスを誤って作成することは、多少なりとも一般的です(nibファイルを優先する理由の1つ)。

すべてのivars(この場合は特にボタン)にアクセサーを使用してもよろしいですか? ivarsへの直接アクセスは、開発者が重複したUI要素を作成する最も一般的な方法です。常にアクセサを使用します(initおよびdeallocを除く)。

+0

細胞を助けるだろうと思い、ちょうどサブクラスではないのUITableViewCellです。ボタンは寿命が短いはずですが、エラーが出たら混乱しました。私はペン先を使用していません。誤って複数のUI要素のインスタンスを作成したことが何を意味するのかよく分かりません。複数のセルがあるので、複数のインスタンスを作成する必要があります。私は自分の質問にコードを追加します。 –

+0

上記のコードが正しいように見えます。実際のクラッシュ情報を掲載することができます。 –

+0

'main'メソッドでスタックトレースが停止しているので、スタックトレースはそれほど役に立ちません。例外は: - [_ UIResizableImage extraButtonPressed:]:インスタンス0x31c480に送られたセレクタが認識できませんでした。そして、これは、ボタンを含むテーブルビューの後、画面から消えていたので(ボタンに触れることはできませんでした) –

-1

お試しください。あなたがremoveTarget、あなたが自己として目標を設定していることを確認してくださいする必要はありません

 if (cell == nil){ 

    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]retain]; 
    UIButton *extraButton = [[UIButton buttonWithType:UIButtonTypeRoundedRect]retain]; 
    [extraButton setFrame:CGRectMake(0, 0, 60, 30)]; 
    [extraButton setTitle:@"Meta" forState:UIControlStateNormal]; 
    [extraButton addTarget:self action:@selector(extraButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; 
    cell.accessoryView = extraButton; 
} 

削除自動解放とTableviewcell配分にとブトン配分に保持追加.....

+0

しかし、これは、それらのかなり多くのリークを作成します。 –

+0

Ok ...あなたのextraButtonPressed:メソッドでは、送信ボタンの(id)をチェックしていると思います。 1つのことをやって、ボタンにasignタグを付け、メソッドでボタンidでそのタグをチェックしてください。私はその方法であなたが認識できないセレクタエラーを持っていると思う..... –

0

。あなたのコードはここでうまく動作します。

0

テーブルビューのセルが再利用キューに入っていて元の状態に戻ってきたと仮定していますが、健全性チェックとして、(cell != nil)がデキューから外れている場合はremoveTargetとにかく目標を再確立する。

基本的には、自分のインライン-prepareForReuse(cell != nil)ケースに入れて、すべての場合に(実際のテーブルセルの割り当てを除いて)全体を設定します。

+0

申し訳ありません私はかなり理解していません。 if文の外側にボタンコードを移動する必要がありますか?それを行うと、各セルに複数のボタンが表示されます。 –

0
[extraButton addTarget:nil action:@selector(extraButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; 
+0

私はそれを削除する方法を知っている、私はこの行を配置する場所を知る必要があります。 –

2

が、私はそれがまあ

[someControl removeTarget:nil 
       action:NULL 
    forControlEvents:UIControlEventAllEvents]; 
関連する問題