程序编译很好,但是当我从主视图控制器移动到详细视图控制器时,我收到了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
答案 0 :(得分:0)
您错过了@
。哈哈:D
它是@avg
,也是@min
@max
..
所以:
[[self.lastMonthsEntries valueForKeyPath:@"@avg.weightInLbs"]floatValue];
等