通过在表视图中删除行来获取SIGABRT

时间:2012-05-03 21:27:09

标签: ios iphone xcode uitableview sigabrt

我试图让一个表视图列表存储在一个数组中的一些对象,除了我尝试删除一行之外它工作正常,它会抛出一个SIGABRT。我检查它是否正确更新阵列。似乎SIGABRT与表中的部分数量有关。以下是表视图控制器的代码:

CalendarViewController.h

#import <UIKit/UIKit.h>
#import "Job.h"
#import "Shift.h"
#import "AppDelegate.h"

@interface CalendarViewController : UITableViewController

@property (nonatomic, strong) NSMutableArray *currentShiftsList;
@property (nonatomic, strong) AppDelegate *dataCenter;

@end

CalendarViewController.m

#import "CalendarViewController.h"

@interface CalendarViewController ()

@property (nonatomic, strong) NSMutableDictionary *sections;
@property (nonatomic, strong) NSArray *sortedShifts;
@property (strong, nonatomic) NSDateFormatter *sectionDateFormatter;
@property (strong, nonatomic) NSDateFormatter *cellDateFormatter;

@end

@implementation CalendarViewController

@synthesize sections, sortedShifts, currentShiftsList, dataCenter, sectionDateFormatter, cellDateFormatter;

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (NSDate *)dateAtBeginningOfDayForDate:(NSDate *)inputDate {

    // Use the user's current calendar and time zone
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSTimeZone *timeZone = [NSTimeZone systemTimeZone];
    [calendar setTimeZone:timeZone];

    // Selectively convert the date components (year, month, day) of the input date
    NSDateComponents *dateComps = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:inputDate];

    // Set the time components manually
    [dateComps setHour:0];
    [dateComps setMinute:0];
    [dateComps setSecond:0];

    // Convert back       
    NSDate *beginningOfDay = [calendar dateFromComponents:dateComps];
    return beginningOfDay;
}

- (NSDate *)dateByAddingYears:(NSInteger)numberOfYears toDate:(NSDate *)inputDate
{
    // Use the user's current calendar
    NSCalendar *calendar = [NSCalendar currentCalendar];

    NSDateComponents *dateComps = [[NSDateComponents alloc] init];
    [dateComps setYear:numberOfYears];

    NSDate *newDate = [calendar dateByAddingComponents:dateComps toDate:inputDate options:0];
    return newDate;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    dataCenter = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    currentShiftsList = [[NSMutableArray alloc] initWithArray:dataCenter.shiftsList];

    self.sectionDateFormatter = [[NSDateFormatter alloc] init];
    [self.sectionDateFormatter setDateStyle:NSDateFormatterLongStyle];
    [self.sectionDateFormatter setTimeStyle:NSDateFormatterNoStyle];

    self.cellDateFormatter = [[NSDateFormatter alloc] init];
    [self.cellDateFormatter setDateStyle:NSDateFormatterNoStyle];
    [self.cellDateFormatter setTimeStyle:NSDateFormatterShortStyle];

    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    self.navigationItem.rightBarButtonItem = self.editButtonItem;

    self.sections = [NSMutableDictionary dictionary];
    for (Shift *shift in dataCenter.shiftsList) {

        // Reduce event start date to date components (year, month, day)
        NSDate *dateRepresentingThisDay = [self dateAtBeginningOfDayForDate:shift.startDate];

        // If we don't yet have an array to hold the events for this day, create one
        NSMutableArray *shiftsOnThisDay = [self.sections objectForKey:dateRepresentingThisDay];
        if (shiftsOnThisDay == nil) {
            shiftsOnThisDay = [NSMutableArray array];

            // Use the reduced date as dictionary key to later retrieve the event list this day
            [self.sections setObject:shiftsOnThisDay forKey:dateRepresentingThisDay];
        }

        // Add the event to the list for this day
        [shiftsOnThisDay addObject:shift];
    }

    // Create a sorted list of days
    NSArray *unsortedShifts = [self.sections allKeys];
    self.sortedShifts = [unsortedShifts sortedArrayUsingSelector:@selector(compare:)];
}



- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return [self.sections count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    NSDate *dateRepresentingThisDay = [self.sortedShifts objectAtIndex:section];
    NSArray *eventsOnThisDay = [self.sections objectForKey:dateRepresentingThisDay];
    return [eventsOnThisDay count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *reuseIdentifier = @"shifts";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];

    NSDate *dateRepresentingThisDay = [self.sortedShifts objectAtIndex:indexPath.section];
    NSArray *eventsOnThisDay = [self.sections objectForKey:dateRepresentingThisDay];
    Shift *shift = [eventsOnThisDay objectAtIndex:indexPath.row];

    cell.textLabel.text = shift.jobtitle;

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"h:mm a"];

    NSString *start = [formatter stringFromDate:shift.startDate];
    NSString *end = [formatter stringFromDate:shift.endDate];

    NSString *detail = [[NSString alloc] initWithFormat:@"%@ to %@", start, end];
    cell.detailTextLabel.text = detail;
    return cell;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    NSDate *dateRepresentingThisDay = [self.sortedShifts objectAtIndex:section];
    return [self.sectionDateFormatter stringFromDate:dateRepresentingThisDay];
}

/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the specified item to be editable.
    return YES;
}
*/


// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source

        [currentShiftsList removeObjectAtIndex:indexPath.row];
        dataCenter.shiftsList = currentShiftsList;

        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }   
    else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }   
}


/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/

/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the item to be re-orderable.
    return YES;
}
*/

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Navigation logic may go here. Create and push another view controller.
    /*
     <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
     // ...
     // Pass the selected object to the new view controller.
     [self.navigationController pushViewController:detailViewController animated:YES];
     */
}

@end

2 个答案:

答案 0 :(得分:0)

这对我没有意义。

[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

为什么不只是:

[tableView deleteRowsAtIndexPaths:indexPath.row withRowAnimation:UITableViewRowAnimationFade];

还要记住删除后重新加载TableView(如果需要)。

答案 1 :(得分:0)

删除行时,您将从currentShiftsList数组中删除一个项目。但是,您没有在UITableViewDataSource相关方法中使用该数组。 TableView期望其DataSource中的项目少一个,但您将返回原始项目数。

总的来说,事情非常混乱,因为您有几个集合试图管理同一组数据(或该数据的副本)。尝试查看CoreData和NSFetchedResultsController,它专门用于管理一组数据并将任何更改传播到UITableView。