0

uitableviewの機能を削除するためにスワイプを実装しています。私はそれを達成することができますが、削除を確認するためのアラートメッセージを表示したいと思います。プログラムでテーブルビューを作成しました。

ViewController.h

@interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
{
    UITableView *tView;
    NSMutableArray *myArray;
    NSIndexPath *lastIndexPath;
}

@property(nonatomic,retain) UITableView *tView;
@property(nonatomic,retain) NSMutableArray *myArray;
@property(nonatomic,retain) NSIndexPath *lastIndexPath;

@end

ViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.view.backgroundColor=[UIColor lightGrayColor];

    myArray = [[NSMutableArray alloc] initWithObjects:@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10", nil];

    // Do any additional setup after loading the view, typically from a nib.
    tView = [[UITableView alloc] initWithFrame:CGRectMake(30, 30, 700, 800) style:UITableViewStylePlain];
    tView.delegate=self;
    tView.dataSource=self;
    [self.view addSubview:tView];
    [tView release];
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 100.0;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [myArray count];
}

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return YES if you want the specified item to be editable.
    return YES;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
{    
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Confirm Delete" message:@"Are you sure?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Delete", nil];

    [alert show];
    [alert release];
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        lastIndexPath = indexPath;
        NSLog(@"%@......%d",lastIndexPath,lastIndexPath.row);
    }
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if(buttonIndex==0)
    {
        NSLog(@"cancel");
    }
    else {
        NSLog(@"delete");
        [myArray removeObjectAtIndex:lastIndexPath.row];    //memory error 
        [tView deleteRowsAtIndexPaths:[NSArray arrayWithObject:lastIndexPath] withRowAnimation:UITableViewRowAnimationFade];
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    //..do required thing and return cell
}

アラートビューのclickButtonAtIndexメソッドでメモリエラーが発生します。これはlastIndexPath用だと思いますが、nslog()はlastIndexPathに正しい値を与えます。私は何が間違っているのですか?

4

1 に答える 1

1

答えが単に「それをすべきではありません」と言うのは嫌いです...だから、エラーが発生する理由を説明し、うまくいけば、なぜこれを行うべきではないのかについて、より良い判断に訴えます( UI の観点)。

所有していない (保持していない) 値を ivar に直接割り当てるため、エラーが発生します。あなたはおそらく言うつもりself.lastIndexPathでした。

何が起こるかというと、アラート ビューが実際には表示されないのは、次に実行ループの時点でindexPath自動解放され、ポインターを介してアクセスしようとするときまでです。

に変更lastIndexPath = indexPath;するとself.lastIndexPath = indexPath;、メモリの問題が解決するはずです。(プロパティを保持としてマークしたので、それを合成し、独自のハンドラーを記述しなかったと仮定すると、self.プレフィックスを使用すると、合成されたアクセサーがそれを保持します)。

(ちなみに、これが、ivar にプロパティとは異なる名前を付けることが悪い考えではない理由です (たとえば、Apple は<property_name>_を使用していますが、私のサイトでは私が使用m<Property_name>しているため、この種の間違いを犯しにくくなっています)。

わかりました...しかし、なぜこれをしてはいけないのかに戻ります....

この時点で、ユーザーは左にスワイプして認識可能なジェスチャーを行い、「削除」とマークされた赤いボタンを押しました...そして、アラートをポップして確認を求めますか? 本当に?よし、必要なら...

于 2012-05-30T08:45:12.427 に答える