tableview崩溃与'*** - [__ NSArrayM insertObject:atIndex:]:对象不能为nil'

时间:2014-06-01 21:09:22

标签: ios uitableview save nsarray

我遇到了问题。 我在ViewController中有一个TableView。这个TableView有5行textFields。每行的高度为156像素。我也有“保存”按钮,点击后我想用以下方法将所有数据保存到NSMutableArray,但结果我收到了一个错误。 我该怎么做? 谢谢

我的方法示例:

- (void) saveDataToArray
{
    carCellTableViewCell * cell;
    _carNewPrices = [[NSMutableArray alloc] init];
    for (int i = 0; i < 5; i++)
    {
        cell = (carCellTableViewCell *)[_meTableView cellForRowAtIndexPath:[NSIndexPath      indexPathForRow:i inSection:0]];
        [_carPrices addObject:cell.priceText.text];
    }
}

这里是cellForRowAtIndexPath:

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
carCellTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
cell.nameLabel.text = [_carNames objectAtIndex:indexPath.row];
cell.priceLabel.text = [NSString stringWithFormat:@"$%@/day",[_carPrices objectAtIndex:indexPath.row]];
cell.infoLabl.text = [_carInfos objectAtIndex:indexPath.row];
switch (indexPath.row) {
    case 0:
    {
        [cell.img setImage:[UIImage imageNamed:@"rolls.jpg"]];
        return cell;
    }
    case 1:
    {
        [cell.img setImage:[UIImage imageNamed:@"bentley.jpg"]];
        return cell;
    }
    case 2:
    {
        [cell.img setImage:[UIImage imageNamed:@"mercedes.jpg"]];
        return cell;
    }
    case 3:
    {
        [cell.img setImage:[UIImage imageNamed:@"bmw.jpg"]];
        return cell;
    }
    case 4:
    {
        [cell.img setImage:[UIImage imageNamed:@"skoda.jpg"]];
    }
    default:
        break;
}

return cell;
}

附加: 在我的tableviewCell中,我有一个标签和一个文本字段。当我点击“保存”时,我想从textField保存我的所有数据并将其发送到标签。

这里是.m文件的所有代码:

#import "carListViewController.h"
#import "carCellTableViewCell.h"
#import "UserSingleton.h"
#import "CheckInternetConnection.h"
#define getCarList @"http:mylink.php" //changed
#define setCarList @"http:mylink.php" //changed
@interface carListViewController ()
@property (weak, nonatomic) IBOutlet UIBarButtonItem *editButtonOutler;
- (IBAction)editButtonOnClick:(id)sender;
@property BOOL editOrSave;//0 when edit, 1 when save
@property UserSingleton * userInfo;
@property NSMutableArray *json;
@property NSMutableArray * carNames;
@property NSMutableArray * carPrices;
@property NSMutableArray * carInfos;
@property NSMutableArray * carNewPrices;
- (void) setData;
@property (weak, nonatomic) IBOutlet UITableView *meTableView;
- (void) saveDataToArray;
- (void) getDataOfCars;
@end

@implementation carListViewController


- (void)viewDidLoad
{
[super viewDidLoad];
self.title = @"List of cars";
// Do any additional setup after loading the view.
}

- (void) viewWillAppear:(BOOL)animated
{
CheckInternetConnection * checkInternet = [[CheckInternetConnection alloc] init];
if (![checkInternet isInternetAvailable])
    [self.navigationController popViewControllerAnimated:YES];
_userInfo = [UserSingleton sharedInstance];
if (_userInfo.priority == 2)
{
    _editButtonOutler.enabled = YES;
    _editButtonOutler.title = @"Edit";
}
else
{
    _editButtonOutler.enabled = NO;
    _editButtonOutler.title = @"";
}
_editOrSave = NO;
[self getDataOfCars];
[_meTableView reloadData];

}

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

- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 5;
}

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
carCellTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
cell.nameLabel.text = [_carNames objectAtIndex:indexPath.row];
cell.priceLabel.text = [NSString stringWithFormat:@"$%@/day",[_carPrices objectAtIndex:indexPath.row]];
cell.infoLabl.text = [_carInfos objectAtIndex:indexPath.row];
switch (indexPath.row) {
    case 0:
    {
        [cell.img setImage:[UIImage imageNamed:@"rolls.jpg"]];
        return cell;
    }
    case 1:
    {
        [cell.img setImage:[UIImage imageNamed:@"bentley.jpg"]];
        return cell;
    }
    case 2:
    {
        [cell.img setImage:[UIImage imageNamed:@"mercedes.jpg"]];
        return cell;
    }
    case 3:
    {
        [cell.img setImage:[UIImage imageNamed:@"bmw.jpg"]];
        return cell;
    }
    case 4:
    {
        [cell.img setImage:[UIImage imageNamed:@"skoda.jpg"]];
    }
    default:
        break;
}

return cell;
}


- (IBAction)editButtonOnClick:(id)sender {
if (_editOrSave == 0)
{
    _editOrSave = 1;
    _editButtonOutler.title = @"Save";
    carCellTableViewCell * cell;
    for (int i = 0; i < 5; i ++)
    {
        cell = (carCellTableViewCell *)[_meTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
        cell.priceLabel.hidden = YES;
        cell.priceText.hidden = NO;
        cell.priceText.text = [[_json objectAtIndex:i] objectForKey:@"cost"];
    }
}
else if (_editOrSave == 1)
{
    _editOrSave = 0;
    carCellTableViewCell * cell;
    for (int i = 0; i < 5; i ++)
    {
        cell = (carCellTableViewCell *)[_meTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
        cell.priceLabel.hidden = NO;
        cell.priceText.hidden = YES;
        [self saveDataToArray];
        [self setData];
        //cell.priceLabel.text = [_carPrices objectAtIndex:i];
    }
    _editButtonOutler.title = @"Edit";
}
[self getDataOfCars];
[_meTableView reloadData];
}

- (void) getDataOfCars
{
_carInfos = [[NSMutableArray alloc] init];
_carNames = [[NSMutableArray alloc] init];
_carPrices = [[NSMutableArray alloc] init];
NSURLRequest* urlRequest =  [NSURLRequest requestWithURL:[NSURL URLWithString:getCarList] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
NSData * data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:nil error:nil];
_json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
carCellTableViewCell * cell;
for (int i = 0; i < _json.count; i ++)
{
    cell = (carCellTableViewCell *)[_meTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
    [_carNames addObject:[[_json objectAtIndex:i] objectForKey:@"name"]];
    [_carPrices addObject:[[_json objectAtIndex:i] objectForKey:@"cost"]];
    [_carInfos addObject:[[_json objectAtIndex:i] objectForKey:@"about"]];
}

}

- (void) setData{
for (int i = 0; i < 5; i ++)
{
    NSMutableString * postString = [NSMutableString stringWithFormat:setCarList];
    [postString appendString:[NSString stringWithFormat:@"?id=%d", i+1]];
    [postString appendString:[NSString stringWithFormat:@"&cost=%@", [_carPrices objectAtIndex:i]]];
    [postString setString:[postString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
    NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:postString]];
    [request setHTTPMethod:@"POST"];
    NSURLConnection * postConnection;
    postConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
}

}

- (void) saveDataToArray
{
carCellTableViewCell * cell;
_carNewPrices = [[NSMutableArray alloc] init];
for (int i = 0; i < 5; i++)
{
    cell = (carCellTableViewCell *)[_meTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
    [_carPrices addObject:cell.priceText.text];
}
}


@end

似乎导致错误,因为并非所有单元格都在屏幕中可见。在我向下滚动之后,现在甚至最后一个单元格在我的onclick编辑按钮后发生了变化。

如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

向行[_carPrices addObject:cell.priceText.text]添加断点,您会看到在某个索引处,文本将为零。我不能告诉你为什么它会是零,因为我不知道你是如何创造细胞的。

答案 1 :(得分:1)

用UITableView中的内容填充数组是颠倒的。这样做的方法是相反的。

换句话说,在代码中的其他位置,您可以确定priceText标签中的内容。如果它是静态表,那么信息可能在IB中,或者如果您正在实施tableview:cellForRowAtIndexPath:,那么您在那里查找priceText。

将这些值放在priceArray中。

您的修改有帮助。这一行:

[NSString stringWithFormat:@"$%@/day",[_carPrices objectAtIndex:indexPath.row]];

是你的朋友,所以:

NSMutableArray *newArrayOfStrings = [NSMutableArray array];

for (int i=0; i<_carPrices.count; i++) {
    NSString *str = [NSString stringWithFormat:@"$%@/day",_carPrices[i]];
    [newArrayOfStrings addObject:str];
}

再次修改。更多代码和评论,更清晰:

声明您的vc实现了UITextFieldDelegate,并声明了一个属性以保留您编辑的价格:

@interface MyViewController <UITextFieldDelegate>

@property (nonatomic, strong) NSMutableArray *editedStrings;

// initialize this with the carPrices after you get these from JSON
self.editedStrings = [_carPrices mutableCopy];  // if they are NSNumbers

// if they are strings, you'll need a deeper copy:
self.editedStrings = [NSMutableArray array];
for (NSString *str in _carPrices) {
    [self.editedStrings addObject:[str copy]];
}

在cellForRowAtIndexPath中,让你的vc成为委托,并标记textFields,以便知道正在编辑哪一个:

cell.priceLabel.delegate = self;
cell.priceLabel.tag = indexPath.row;

然后在用户编辑时实现委托方法:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {

    NSInteger index = textField.tag;
    NSString *candidateString = [textField.text stringByReplacingCharactersInRange:range withString:string];
    [self.editedStrings replaceObjectAtIndex:index withObject: candidateString];

    return YES;
}