移动到详细信息表时,SIGABRT崩溃

时间:2014-05-21 18:05:56

标签: ios objective-c uitableview

程序编译很好,但是当我从主视图控制器移动到详细视图控制器时,我收到了SIGABRT错误。调试器突出显示问题行,我已经注释掉了,但我仍然无法弄清楚问题。

HistoryTableViewController.h

#import <UIKit/UIKit.h>
@class WeightHistoryDocument;

@interface HistoryTableViewController : UITableViewController

@property (strong, nonatomic)WeightHistoryDocument *weightHistoryDocument;

@end

HistoryTableViewController.m

#import "HistoryTableViewController.h"
#import "EntryDetailViewController.h"
#import "WeightHistoryDocument.h"
#import "WeightEntry.h"
#import "HistoryCell.h"

@interface HistoryTableViewController ()

@property (strong, nonatomic)id documentBeganObserver;
@property (strong, nonatomic)id documentInsertedObserver;
@property (strong, nonatomic)id documentDeletedObserver;
@property (strong, nonatomic)id documentChangeCompleteObserver;

@end

@implementation HistoryTableViewController

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

-(void)dealloc
{
    [self removeNotifications];
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    // 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;
}

// TODO: Delete this after testing!
//-(void)viewDidAppear:(BOOL)animated
//{
//    [super viewDidAppear:animated];
//    // NSLog(@"%@ appeared", [self class]);
//    NSLog(@"%@ appeared, document = %@", [self class], self.weightHistoryDocument);
//}


- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView  // unused parameter 'tableView'
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section // unused parameter 'tableView'
{
    return (NSInteger)self.weightHistoryDocument.count;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"HistoryCell";

    HistoryCell *cell =
    [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    [self configureCell:cell forIndexPath:indexPath];

    return cell;
}


/*
// 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
        [tableView deleteRowsAtIndexPaths:@[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 - Accessor Methods
-(void)setWeightHistoryDocument:(WeightHistoryDocument *)weightHistoryDocument
{
    if (_weightHistoryDocument)
    {
        [self removeNotifications];
    }

    _weightHistoryDocument = weightHistoryDocument;
    {
        [self setupNotifications];
    }
}


#pragma mark - Navigation

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"EntryDetailSegue"]) {
        [self configureWeightEntryViewController:segue.destinationViewController];
    }
}

- (void)setupNotifications
{
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
    WeightHistoryDocument *doc = self.weightHistoryDocument;
    __weak HistoryTableViewController *_self = self;

    self.documentBeganObserver =
    [center
     addObserverForName:WeightHistoryDocumentBeginChangesNotification
     object:doc
     queue:mainQueue
     usingBlock:^(NSNotification *note) { // unused parameter 'note'
         if ([_self isViewLoaded])
         {
             [_self.tableView beginUpdates];
         }
     }];

    self.documentInsertedObserver =
    [center
     addObserverForName:WeightHistoryDocumentInsertWeightEntryNotification
     object:doc
     queue:mainQueue
     usingBlock:^(NSNotification *note) {
         NSIndexPath *indexPath =
         note.userInfo[WeightHistoryDocumentNotificationIndexPathKey];
         NSAssert(indexPath != nil,
                  @"We should have an index path in the "
                  @"notification's user info dictionary");

         if ([_self isViewLoaded])
         {
             [_self.tableView
              insertRowsAtIndexPaths:@[indexPath]
              withRowAnimation:UITableViewRowAnimationAutomatic];
         }
     }];

    self.documentDeletedObserver =
    [center
     addObserverForName:WeightHistoryDocumentDeleteWeightEntryNotification
     object:doc
     queue:mainQueue
     usingBlock:^(NSNotification *note) {
         NSIndexPath *indexPath =
         note.userInfo[WeightHistoryDocumentNotificationIndexPathKey];
         NSAssert(indexPath != nil,
                  @"We should have an index path in the "
                  @"notification's user info dictionary");

         if ([_self isViewLoaded])
         {
             [_self.tableView
              deleteRowsAtIndexPaths:@[indexPath]
              withRowAnimation:UITableViewRowAnimationAutomatic];
         }
     }];

    self.documentChangeCompleteObserver =
    [center
     addObserverForName:WeightHistoryDocumentChangesCompleteNotification
     object:doc
     queue:mainQueue
     usingBlock:^(NSNotification *note) { // unused parameter 'note'
         [_self.tableView endUpdates];
     }];
}

-(void)removeNotifications
{
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];

    if (self.documentBeganObserver)
    {
        [center removeObserver:self.documentBeganObserver];
        self.documentBeganObserver = nil;
    }

    if(self.documentInsertedObserver)
    {
        [center removeObserver:self.documentInsertedObserver];
        self.documentInsertedObserver = nil;
    }
}

#pragma mark - Private Methods

-(void)configureCell:(HistoryCell *)cell forIndexPath:(NSIndexPath *)indexPath
{
    WeightEntry *entry = [self.weightHistoryDocument entryAtIndexPath:indexPath];

    cell.weightLabel.text = [entry stringForWeightInUnit:getDefaultUnits()];

    cell.dateLabel.text = [NSDateFormatter localizedStringFromDate:entry.date
                                                         dateStyle:NSDateFormatterShortStyle
                                                         timeStyle:NSDateFormatterShortStyle];
}

-(void)configureWeightEntryViewController:(EntryDetailViewController *)controller
{
    NSIndexPath *selectedPath = [self.tableView indexPathForSelectedRow];
    WeightEntry *entry = [self.weightHistoryDocument entryAtIndexPath:selectedPath];

    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

    NSDateComponents *dateComponents = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit |NSDayCalendarUnit fromDate:entry.date];

    [dateComponents setMonth:[dateComponents month] -1];
    NSDate *lastMonth = [calendar dateFromComponents:dateComponents];

    controller.entry = entry;

    controller.lastMonthsEntries = [self.weightHistoryDocument weightEntriesAfter:lastMonth before:entry.date];
}


@end

EntryDetailViewController.h

#import <UIKit/UIKit.h>
@class WeightEntry;

@interface EntryDetailViewController : UITableViewController

@property (strong, nonatomic) WeightEntry *entry;
@property (strong, nonatomic) NSArray *lastMonthsEntries;

@end

EntryDetailViewController.m(注释掉SIGABRT错误行)

#import "EntryDetailViewController.h"
#import "WeightEntry.h"

@interface EntryDetailViewController ()

@property (strong, nonatomic) IBOutlet UITextField *weightTextField;
@property (strong, nonatomic) IBOutlet UITextField *dateTextField;
@property (strong, nonatomic) IBOutlet UITextField *averageTextField;
@property (strong, nonatomic) IBOutlet UITextField *lossTextField;
@property (strong, nonatomic) IBOutlet UITextField *gainTextField;
@end

@implementation EntryDetailViewController

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self updateUI];
}

// TODO: Delete this after testing!
//-(void)viewDidAppear:(BOOL)animated
//{
//    [super viewDidAppear:animated];
//    NSLog(@"%@ appeared, entry = %@", [self class], self.entry);
//}

#pragma mark - Private Methods

-(void)updateUI
{
    WeightUnit unit = getDefaultUnits();
    self.weightTextField.text = [self.entry stringForWeightInUnit:unit];

    self.dateTextField.text =
    [NSDateFormatter localizedStringFromDate:self.entry.date
                                   dateStyle:NSDateFormatterMediumStyle
                                   timeStyle:NSDateFormatterShortStyle];

    float average = [[self.lastMonthsEntries valueForKeyPath:@"avg.weightInLbs"]floatValue]; //Thread 1: signal SIGABRT

    float min = [[self.lastMonthsEntries valueForKeyPath:@"min.weightInLbs"]floatValue];

    float max = [[self.lastMonthsEntries valueForKeyPath:@"max.weightInLbs"] floatValue];

    float lossFromMax = max - self.entry.weightInLbs;
    NSAssert(lossFromMax >= 0.0f, @"This should always be a non-negative number");

    float gainFromMin = self.entry.weightInLbs - min;
    NSAssert(gainFromMin >= 0.0f, @"This should always be a non-negative number");

    self.averageTextField.text = [WeightEntry stringForWeightInLbs:average ofUnit:unit];

    self.gainTextField.text = [WeightEntry stringForWeightInLbs:gainFromMin ofUnit:unit];

    self.gainTextField.text = [WeightEntry stringForWeightInLbs:lossFromMax ofUnit:unit];
}


@end

1 个答案:

答案 0 :(得分:0)

您错过了@。哈哈:D

它是@avg,也是@min @max ..

所以:

[[self.lastMonthsEntries valueForKeyPath:@"@avg.weightInLbs"]floatValue];