0

我正在实现滑动以删除 uitableview 中的功能。我能够做到这一点,但现在我希望显示一条警报消息以确认删除。我以编程方式创建了 tableview。

视图控制器.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

视图控制器.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

当答案只是说“你不应该这样做”时,我讨厌它......所以我会解释你为什么会出错,然后希望你能更好地判断为什么你真的不应该这样做(来自用户界面的观点)。

您收到一个错误,因为您将一个您不拥有的值(您没有保留它)直接分配给一个 ivar。你可能是想说self.lastIndexPath

发生的情况是警报视图直到下一次通过运行循环时才真正出现,此时indexPath已自动释放并且您尝试通过指针访问它。

更改lastIndexPath = indexPath;self.lastIndexPath = indexPath;应该可以解决内存问题。(由于您将属性标记为保留,假设您合成了它并且没有编写自己的处理程序,当您使用self.前缀时,合成访问器将为您保留它)。

(顺便说一句,这就是为什么将您的 ivars 命名为与您的属性不同的名称并不是一个坏主意(例如,Apple 使用<property_name>_,在我的网站上我使用m<Property_name>它使得很难犯这种错误)。

好的......但是回到为什么你不应该这样做......

此时,您的用户通过向左滑动做出了可识别的手势,然后按下了标记为“删除”的红色按钮......现在您要弹出警报并要求他们确认?真的吗?好吧,如果你必须...

于 2012-05-30T08:45:12.427 回答