2012-06-03 24 views
0

刪除了不應該在那裏的冒號,因爲我的選擇器沒有。它固定它,然後發生了這樣的問題:未捕獲的異常錯誤!簡單的文檔應用程序

2012-06-02 22:33:10.083 TinyPix[10433:fb03] load OK 
2012-06-02 22:33:10.084 TinyPix[10433:fb03] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<BIDTinyPixDocument 0x6e665a0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key timeStamp.' 
*** First throw call stack: 
(0x16b0022 0x1841cd6 0x16afee1 0x9c8efe 0x937831 0x936c99 0x5f47 0x5e77 0x93af30 0x93aedb 0x59ed 0x4546e3 0x40778d9 0x4078509 0x15e7803 0x15e6d84 0x15e6c9b 0x15997d8 0x159988a 0x1b626 0x2a5d 0x29c5) 
terminate called throwing an exception 

這是我的詳細文件:我在self.detailDescriptionLabel.text線得到一個SIGABRT錯誤。不知道發生了什麼事。

#import "BIDDetailViewController.h" 

@interface BIDDetailViewController() 
- (void)configureView; 
@end 

@implementation BIDDetailViewController 

@synthesize detailItem = _detailItem; 
@synthesize detailDescriptionLabel = _detailDescriptionLabel; 

#pragma mark - Managing the detail item 

- (void)setDetailItem:(id)newDetailItem 
{ 
    if (_detailItem != newDetailItem) { 
     _detailItem = newDetailItem; 

     // Update the view. 
     [self configureView]; 
    } 
} 

- (void)configureView 
{ 
    // Update the user interface for the detail item. 

    if (self.detailItem) { 
     self.detailDescriptionLabel.text = [[self.detailItem valueForKey:@"timeStamp"] description]; 
    } 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 
    [self configureView]; 
} 

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

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

@end 

這是我的文件:

#import "BIDMasterViewController.h" 
#import "BIDTinyPixDocument.h" 

#import "BIDDetailViewController.h" 

@interface BIDMasterViewController() <UIAlertViewDelegate> 

@property (strong, nonatomic) NSArray *documentFilenames; 
@property (strong, nonatomic) BIDTinyPixDocument *chosenDocument; 
-(NSURL *)urlForFilename:(NSString *)filename; 
-(void)reloadFiles; 
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath; 
@end 

@implementation BIDMasterViewController 
@synthesize colorControl; 
@synthesize documentFilenames; 
@synthesize chosenDocument; 

@synthesize fetchedResultsController = __fetchedResultsController; 
@synthesize managedObjectContext = __managedObjectContext; 

- (void)awakeFromNib 
{ 
    [super awakeFromNib]; 
} 

-(void)viewWillAppear:(BOOL)animated; 
{ 
    [super viewWillAppear:animated]; 
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; 
    NSInteger selectedColorIndex = [prefs integerForKey:@"selectedColorIndex"]; 
    self.colorControl.selectedSegmentIndex = selectedColorIndex; 

} 


- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 
    self.navigationItem.leftBarButtonItem = self.editButtonItem; 

    UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)]; 
    self.navigationItem.rightBarButtonItem = addButton; 

    [self reloadFiles]; 
} 

- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 
    // Release any retained subviews of the main view. 
} 

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

- (void)insertNewObject 
{ 
// get the name 
    UIAlertView *alert = 
    [[UIAlertView alloc] initWithTitle:@"Filename" 
           message:@"Enter a name for your new TinyPix document." 
           delegate:self 
        cancelButtonTitle:@"Cancel" 
        otherButtonTitles:@"Create", nil]; 
    alert.alertViewStyle = UIAlertViewStylePlainTextInput; 
    [alert show]; 
} 

#pragma mark - Table View 



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

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    if (editingStyle == UITableViewCellEditingStyleDelete) { 
     NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext]; 
     [context deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]]; 

     NSError *error = nil; 
     if (![context save:&error]) { 
      // Replace this implementation with code to handle the error appropriately. 
      // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
      abort(); 
     } 
    } 
} 

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    // The table view should not be re-orderable. 
    return NO; 
} 



#pragma mark - Fetched results controller 

- (NSFetchedResultsController *)fetchedResultsController 
{ 
    if (__fetchedResultsController != nil) { 
     return __fetchedResultsController; 
    } 

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    // Edit the entity name as appropriate. 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:self.managedObjectContext]; 
    [fetchRequest setEntity:entity]; 

    // Set the batch size to a suitable number. 
    [fetchRequest setFetchBatchSize:20]; 

    // Edit the sort key as appropriate. 
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO]; 
    NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil]; 

    [fetchRequest setSortDescriptors:sortDescriptors]; 

    // Edit the section name key path and cache name if appropriate. 
    // nil for section name key path means "no sections". 
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Master"]; 
    aFetchedResultsController.delegate = self; 
    self.fetchedResultsController = aFetchedResultsController; 

    NSError *error = nil; 
    if (![self.fetchedResultsController performFetch:&error]) { 
     // Replace this implementation with code to handle the error appropriately. 
     // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
     abort(); 
    } 

    return __fetchedResultsController; 
}  

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller 
{ 
    [self.tableView beginUpdates]; 
} 

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo 
      atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type 
{ 
    switch(type) { 
     case NSFetchedResultsChangeInsert: 
      [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 

     case NSFetchedResultsChangeDelete: 
      [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 
    } 
} 

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject 
     atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type 
     newIndexPath:(NSIndexPath *)newIndexPath 
{ 
    UITableView *tableView = self.tableView; 

    switch(type) { 
     case NSFetchedResultsChangeInsert: 
      [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 

     case NSFetchedResultsChangeDelete: 
      [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 

     case NSFetchedResultsChangeUpdate: 
      [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath]; 
      break; 

     case NSFetchedResultsChangeMove: 
      [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade]; 
      break; 
    } 
} 

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller 
{ 
    [self.tableView endUpdates]; 
} 

/* 
// Implementing the above methods to update the table view in response to individual changes may have performance implications if a large number of changes are made simultaneously. If this proves to be an issue, you can instead just implement controllerDidChangeContent: which notifies the delegate that all section and object changes have been processed. 

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller 
{ 
    // In the simplest, most efficient, case, reload the table view. 
    [self.tableView reloadData]; 
} 
*/ 

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath 
{ 
    NSManagedObject *object = [self.fetchedResultsController objectAtIndexPath:indexPath]; 
    cell.textLabel.text = [[object valueForKey:@"timeStamp"] description]; 
} 

-(NSURL *)urlForFilename:(NSString *)filename { 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentDirectory = [paths objectAtIndex:0]; 
    NSString *filePath = [documentDirectory stringByAppendingPathComponent:filename]; 
    NSURL *url = [NSURL fileURLWithPath:filePath]; 
    return url; 
} 

-(void)reloadFiles { 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *path = [paths objectAtIndex:0]; 
    NSFileManager *fm = [NSFileManager defaultManager]; 

    NSError *dirError; 
    NSArray *files = [fm contentsOfDirectoryAtPath:path error:&dirError]; 
    if (!files) { 
     NSLog(@"Encountered error while trying to list files in directory %@: %@", path, dirError); 
    } 

    NSLog(@"found files: %@", files); 

    files = [files sortedArrayUsingComparator:^NSComparisonResult(id filename1, id filename2) { 
     NSDictionary *attr1 = [fm attributesOfItemAtPath:[path stringByAppendingPathComponent:filename1] 
                error:nil]; 
     NSDictionary *attr2 = [fm attributesOfItemAtPath:[path stringByAppendingPathComponent:filename2] 
                         error:nil]; 
           return [[attr2 objectForKey:NSFileCreationDate] compare:[attr1 objectForKey:NSFileCreationDate]]; 
           }]; 

     self.documentFilenames = files; 
     [self.tableView reloadData]; 

} 

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

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    return [self.documentFilenames count]; 
} 

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

    NSString *path = [self.documentFilenames objectAtIndex:indexPath.row]; 
    cell.textLabel.text = path.lastPathComponent.stringByDeletingPathExtension; 
    return cell; 
} 


-(IBAction)chooseColor:(id)sender { 
    NSInteger selectedColorIndex = [(UISegmentedControl *)sender selectedSegmentIndex]; 
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; 
    [prefs setInteger:selectedColorIndex forKey:@"selectedColorIndex"]; 
} 


-(void)alertView:(UIAlertView *)alertView 
didDismissWithButtonIndex:(NSInteger)buttonIndex { 
    if (buttonIndex == 1) { 
     NSString *filename = [NSString stringWithFormat:@"%@.tinypix", 
           [alertView textFieldAtIndex:0].text]; 
     NSURL *saveUrl = [self urlForFilename:filename]; 
     self.chosenDocument = [[BIDTinyPixDocument alloc] initWithFileURL:saveUrl]; 
     [chosenDocument saveToURL:saveUrl 
       forSaveOperation:UIDocumentSaveForCreating 
       completionHandler:^(BOOL success) { 
        if (success) { 
         NSLog(@"save OK"); 
         [self reloadFiles]; 
         [self performSegueWithIdentifier:@"masterToDetail" 
                sender:self]; 
        } else { 
         NSLog(@"failed to save!"); 
        } 
       }]; 
    } 
} 


-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
    if (sender == self) { 
     // if sender == self, a new document has just been created, 
     // and chosenDocument is already set. 

     UIViewController *destination = segue.destinationViewController; 
     if ([destination respondsToSelector:@selector(setDetailItem:)]) { 
      [destination setValue:self.chosenDocument forKey:@"detailItem"]; 
     } 
    }else { 
     // find the chose document from the tableview 
     NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; 
     NSString *filename = [documentFilenames objectAtIndex:indexPath.row]; 
     NSURL *docUrl = [self urlForFilename:filename]; 
     self.chosenDocument = [[BIDTinyPixDocument alloc] initWithFileURL:docUrl]; 
     [self.chosenDocument openWithCompletionHandler:^(BOOL success) { 
      if (success) { 
       NSLog(@"load OK"); 
       UIViewController *destination = segue.destinationViewController; 
       if ([destination respondsToSelector:@selector(setDetailItem:)]) { 
        [destination setValue:self.chosenDocument forKey:@"detailItem"]; 
       } 
      }else { 
       NSLog(@"failed to load!"); 
      } 
     }]; 
    } 
} 
@end 

回答

1

您作爲insertNewObject:指定選擇和最終結腸說,它需要一個參數。您實現的insertNewObject方法不接受任何參數,對於Objective-C,這使得它不同,並且找不到一個參數方法。

您應該將您的實施更改爲- (IBAction)insertNewObject:(id)sender {...}以匹配@selector(insertNewObject:)

+0

這工作,但導致上述問題 – Devj

+0

沒有任何人,我從書源代碼下載了確切的項目,它仍然無法正常工作。真是笑話。謝謝你的時間 – Devj

相關問題