Terminating the exception


#1

can you look through these code and try to figure out why it keeps terminating the exception?? i understand what I’m doing but i can’t figure out what is stopping my program.
– thanks
BNRImageStore.h

[code]#import <UIKit/UIKit.h>

@interface BNRImageStore : NSObject
{
NSMutableDictionary *dictionary;
}

  • (BNRImageStore *)sharedStore;
  • (void)setImage:(UIImage *)i forKey:(NSString *)s;
  • (UIImage *)imageForKey:(NSString *)s;
  • (void)deleteImageForKey:(NSString *)s;

@end[/code]

BNRImageStore.m

[code]#import “BNRImageStore.h”

@implementation BNRImageStore

  • (id)allocWithZone:(NSZone *)zone
    {
    return [self sharedStore];
    }

  • (BNRImageStore *)sharedStore
    {
    static BNRImageStore *sharedStore = nil;
    if (!sharedStore) {
    // Create the singleton
    sharedStore = [[super allocWithZone:NULL] init];
    }
    return sharedStore;
    }

  • (id)init
    {
    self = [super init];
    if (self) {
    dictionary = [[NSMutableDictionary alloc] init];
    }
    return self;
    }

  • (void)setImage:(UIImage *)i forKey:(NSString *)s
    {
    [dictionary setObject:i forKey:s];
    }

  • (UIImage *)imageForKey:(NSString *)s
    {
    return [dictionary objectForKey:s];
    }

  • (void)deleteImageForKey:(NSString *)s
    {
    if (!s)
    return;
    [dictionary removeObjectForKey:s];
    }
    @end[/code]

BNRItemStore.h

[code]#import <Foundation/Foundation.h>

@class BNRItem;

@interface BNRItemStore : NSObject
{
NSMutableArray *allItems;
}
// Notice that this is a class method and prefixed whit a + instead of a -

  • (BNRItemStore *)sharedStore;
  • (void)removeItem:(BNRItem *)p;

  • (NSArray *)allItems;

  • (BNRItem *)createItem;

  • (void)moveItemAtIndex:(int)from
    toIndex:(int)to;

  • (NSString *)itemArchivePath;

  • (BOOL)saveChanges;
    @end[/code]

BNRItemStore.m

[code]#import “BNRItemStore.h”
#import “BNRItem.h”

@implementation BNRItemStore

  • (BNRItemStore *)sharedStore
    {
    static BNRItemStore *sharedStore = nil;
    if (!sharedStore)
    sharedStore = [[super allocWithZone:nil] init];

    return sharedStore;
    }

  • (id)allocWithZone:(NSZone *)zone
    {
    return [self sharedStore];
    }

  • (id)init
    {
    self = [super init];
    if (self) {
    NSString *path = [self itemArchivePath];
    allItems = [NSKeyedUnarchiver unarchiveObjectWithFile:path];

      // If the array hadn't been saved previously, create a new empty one
      if (!allItems)
          allItems = [[NSMutableArray alloc] init];
    

    }

    return self;
    }

  • (NSArray *)allItems
    {
    return allItems;
    }

  • (BNRItem *)createItem
    {
    BNRItem *p = [BNRItem randomItem];

    [allItems addObject:p];

    return p;
    }

  • (void)removeItem:(BNRItem *)p
    {
    [allItems removeObjectIdenticalTo:p];
    }

  • (void)moveItemAtIndex:(int)from toIndex:(int)to
    {
    if (from == to) {
    return;
    }
    // Get pointer to object being moved do we can re-insert it
    BNRItem *p = [allItems objectAtIndex:from];

    // Remove p from array
    [allItems removeObjectAtIndex:from];

    // Insert p in array at new location
    [allItems insertObject:p atIndex:to];

}

  • (NSString *)itemAchrivePath
    {
    NSArray *documentDirectories =
    NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    // Get one and only document directory from that list
    NSString *documentDirectory = [documentDirectories objectAtIndex:0];

    return [documentDirectory stringByAppendingPathComponent:@“items.archive”];
    }

  • (BOOL)saveChanges
    {
    // returns success or failure
    NSString *path = [self itemArchivePath];

    return [NSKeyedArchiver archiveRootObject:allItems
    toFile:path];
    }
    @end[/code]

BNRItem.h

[code]#import “BNRItemStore.h”
#import “BNRItem.h”

@implementation BNRItemStore

  • (BNRItemStore *)sharedStore
    {
    static BNRItemStore *sharedStore = nil;
    if (!sharedStore)
    sharedStore = [[super allocWithZone:nil] init];

    return sharedStore;
    }

  • (id)allocWithZone:(NSZone *)zone
    {
    return [self sharedStore];
    }

  • (id)init
    {
    self = [super init];
    if (self) {
    NSString *path = [self itemArchivePath];
    allItems = [NSKeyedUnarchiver unarchiveObjectWithFile:path];

      // If the array hadn't been saved previously, create a new empty one
      if (!allItems)
          allItems = [[NSMutableArray alloc] init];
    

    }

    return self;
    }

  • (NSArray *)allItems
    {
    return allItems;
    }

  • (BNRItem *)createItem
    {
    BNRItem *p = [BNRItem randomItem];

    [allItems addObject:p];

    return p;
    }

  • (void)removeItem:(BNRItem *)p
    {
    [allItems removeObjectIdenticalTo:p];
    }

  • (void)moveItemAtIndex:(int)from toIndex:(int)to
    {
    if (from == to) {
    return;
    }
    // Get pointer to object being moved do we can re-insert it
    BNRItem *p = [allItems objectAtIndex:from];

    // Remove p from array
    [allItems removeObjectAtIndex:from];

    // Insert p in array at new location
    [allItems insertObject:p atIndex:to];

}

  • (NSString *)itemAchrivePath
    {
    NSArray *documentDirectories =
    NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    // Get one and only document directory from that list
    NSString *documentDirectory = [documentDirectories objectAtIndex:0];

    return [documentDirectory stringByAppendingPathComponent:@“items.archive”];
    }

  • (BOOL)saveChanges
    {
    // returns success or failure
    NSString *path = [self itemArchivePath];

    return [NSKeyedArchiver archiveRootObject:allItems
    toFile:path];
    }
    @end[/code]

BNRItem.m

[code]
#import “BNRItem.h”

@implementation BNRItem
@synthesize itemName;
@synthesize containedItem, container, serialNumber, valueInDollars, dateCreated;
@synthesize imageKey;

  • (id)randomItem
    {
    // Create an array of three adjectives
    NSArray *randomAdjectiveList = [NSArray arrayWithObjects:@“Fluffy”,
    @“Rusty”,
    @“Shiny”, nil];
    // Create an array of three nouns
    NSArray *randomNounList = [NSArray arrayWithObjects:@“Bear”,
    @“Spork”,
    @“Mac”, nil];
    // Get the index of a random adjective/noun from the lists
    // Note: The % operator, called the modulo operator, gives
    // you the remainder. So adjectiveIndex is a random number
    // from 0 to 2 inclusive.
    NSInteger adjectiveIndex = rand() % [randomAdjectiveList count];
    NSInteger nounIndex = rand() % [randomNounList count];

    // Note that NSInteger is not an object, but a type definition
    // for “unsigned long”

    NSString *randomName = [NSString stringWithFormat:@"%@ %@",
    [randomAdjectiveList objectAtIndex:adjectiveIndex],
    [randomNounList objectAtIndex:nounIndex]];
    int randomValue = rand() % 100;
    NSString *randomSerialNumber = [NSString stringWithFormat:@"%c%c%c%c%c",
    ‘0’ + rand() % 10,
    ‘A’ + rand() % 26,
    ‘0’ + rand() % 10,
    ‘A’ + rand() % 26,
    ‘0’ + rand() % 10];
    // Once again, ignore the memory problems with this method
    BNRItem *newItem =
    [[self alloc] initWithItemName:randomName
    valueInDollars:randomValue
    serialNumber:randomSerialNumber];
    return newItem;
    }

  • (id)initWithItemName:(NSString *)name
    valueInDollars:(int)value
    serialNumber:(NSString *)sNumber
    {
    // Call the superclass’s designated initializer
    self = [super init];

    // Did the superclass’s designated initializer succeed?
    if(self) {
    // Give the instance variables initial values
    [self setItemName:name];
    [self setSerialNumber:sNumber];
    [self setValueInDollars:value];
    dateCreated = [[NSDate alloc] init];
    }

    // Return the address of the newly initialized object
    return self;
    }

  • (id)init
    {
    return [self initWithItemName:@“Possession"
    valueInDollars:0
    serialNumber:@”"];
    }

  • (void)setContainedItem:(BNRItem *)i
    {
    containedItem = i;
    [i setContainer:self];
    }

  • (NSString *)description
    {
    NSString *descriptionString =
    [[NSString alloc] initWithFormat:@"%@ (%@): Worth $%d, recorded on %@",
    itemName,
    serialNumber,
    valueInDollars,
    dateCreated];
    return descriptionString;
    }

  • (void)dealloc
    {
    NSLog(@“Destroyed: %@”, self);
    }

  • (void)encodeWithCoder:(NSCoder *)aCoder
    {
    [aCoder encodeObject:itemName forKey:@“itemName”];
    [aCoder encodeObject:serialNumber forKey:@“serialNumber”];
    [aCoder encodeObject:dateCreated forKey:@“dateCreated”];
    [aCoder encodeObject:imageKey forKey:@“imageKey”];

    [aCoder encodeInt:valueInDollars forKey:@“vauleInDollars”];
    }

  • (id)initWithCoder:(NSCoder *)aDecoder
    {
    self = [super init];
    if (self) {
    [self setItemName:[aDecoder decodeObjectForKey:@“itemName”]];
    [self setSerialNumber:[aDecoder decodeObjectForKey:@“serialNumber”]];
    [self setImageKey:[aDecoder decodeObjectForKey:@“imageKey”]];

      [self setValueInDollars:[aDecoder decodeIntForKey:@"valueInDollars"]];
      
      dateCreated = [aDecoder decodeObjectForKey:@"dateCreated"];
    

    }
    return self;
    }
    @end[/code]
    ItemsViewController.h[code]#import <Foundation/Foundation.h>
    #import “DetailViewController.h”

@interface ItemsViewController : UITableViewController

  • (IBAction)addNewItem:(id)sender;

@end[/code]

ItemsViewController.m

[code]#import “ItemsViewController.h”
#import “BNRItemStore.h”
#import “BNRItem.h”

@implementation ItemsViewController

  • (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
    DetailViewController *detailViewController = [[DetailViewController alloc] initForNewItem:NO];

    NSArray *items = [[BNRItemStore sharedStore] allItems];
    BNRItem *selectedItem = [items objectAtIndex:[indexPath row]];

    // Give detail view controller a pointer to the item object in row
    [detailViewController setItem:selectedItem];

    // Push in onto the top of the navigation controller’s stack
    [[self navigationController] pushViewController:detailViewController animated:YES];
    }

  • (id)init
    {
    // Call the superclass’s designated initializer
    self = [super initWithStyle:UITableViewStyleGrouped];
    if (self) {
    UINavigationItem *n = [self navigationItem];

      [n setTitle:@"Homepwner"];
      
      // Create a new bar button item that will send addNewItem: to ItemsViewController
      UIBarButtonItem *bbi = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addNewItem:)];
      
      // Set this bar button item as the right item in the navigationItem
      [[self navigationItem] setRightBarButtonItem:bbi];
      
      [[self navigationItem] setLeftBarButtonItem:[self editButtonItem]];
    

    }
    return self;
    }

  • (id)initWithStyle:(UITableViewStyle)style
    {
    return [self init];
    }

  • (NSInteger)tableView:(UITableView *)tableView
    numberOfRowsInSection:(NSInteger)section
    {
    return [[[BNRItemStore sharedStore] allItems] count];
    }

  • (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    // Create for a reusable cell first, use that if it exists
    UITableViewCell *cell =
    [tableView dequeueReusableCellWithIdentifier:@“UITableViewCell”];

    // If there is no reusable cell of this type, create a new one
    if (!cell) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@“UITableViewCell”];
    }

    // Set the text on the cell with the description of the item that is at the nth index of items, where n = row this cell will appear in on the tableview
    BNRItem *p = [[[BNRItemStore sharedStore] allItems] objectAtIndex:[indexPath row]];

    [[cell textLabel] setText:[p description]];

    return cell;
    }

  • (IBAction)addNewItem:(id)sender
    {
    // Create a new BNRItem and add it to the store
    BNRItem *newItem = [[BNRItemStore sharedStore] createItem];

    DetailViewController *detailViewController = [[DetailViewController alloc] initForNewItem:YES];

    [detailViewController setItem:newItem];

    [detailViewController setDismissBlock:^{
    [[self tableView] reloadData];
    }];

    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:detailViewController];

    [navController setModalPresentationStyle:UIModalPresentationFullScreen];
    [navController setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];

    [self presentViewController:navController animated:YES completion:nil];
    }

  • (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
    {
    // If the table view is asking to commit a delete command…
    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
    BNRItemStore *ps = [BNRItemStore sharedStore];
    NSArray *items = [ps allItems];
    BNRItem *p = [items objectAtIndex:[indexPath row]];
    [ps removeItem:p];

      // We also remove that row from the table view with an animation
      [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    

    }

}

  • (void)tableView:(UITableView *)tableView
    moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
    {
    [[BNRItemStore sharedStore] moveItemAtIndex:[sourceIndexPath row] toIndex:[destinationIndexPath row]];
    }

  • (void)viewWillDisappear:(BOOL)animated
    {
    [super viewWillAppear];
    [[self tableView] reloadData];
    }

@end[/code]

HomepwnerAppDelegate.h

[code]#import <UIKit/UIKit.h>

@interface HomepwnerAppDelegate : UIResponder

@property (strong, nonatomic) UIWindow *window;

@end[/code]

HomepwnerAppDelegate.m

[code]#import “HomepwnerAppDelegate.h”
#import “ItemsViewController.h”
#import “BNRItemStore.h”

@implementation HomepwnerAppDelegate

  • (void)applicationDidEnterBackground:(UIApplication *)application
    {
    BOOL success = [[BNRItemStore sharedStore] saveChanges];
    if (success) {
    NSLog(@“Saved all of the BNRItems”);
    } else {
    NSLog(@“Could not save any of the BNRItems”);
    }
    }

  • (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.

    // Create a ItemsViewController
    ItemsViewController *itemsViewController = [[ItemsViewController alloc] init];

    // Create an instance of a UINavigationController its stack contains only itemsViewController
    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:itemsViewController];

    // Place navagation controller’s view in the window heirarchy
    [[self window] setRootViewController:navController];

    self.window.backgroundColor = [UIColor blueColor];
    [self.window makeKeyAndVisible];
    return YES;
    }

  • (void)applicationWillResignActive:(UIApplication *)application
    {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    }

  • (void)applicationWillEnterForeground:(UIApplication *)application
    {
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
    }

  • (void)applicationDidBecomeActive:(UIApplication *)application
    {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }

  • (void)applicationWillTerminate:(UIApplication *)application
    {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }

@end[/code]

DetailViewController.h

[code]
#import <UIKit/UIKit.h>

@class BNRItem;

@interface DetailViewController : UIViewController
<UINavigationControllerDelegate, UIImagePickerControllerDelegate, UITextFieldDelegate, UIPopoverControllerDelegate>
{

__weak IBOutlet UITextField *nameField;
__weak IBOutlet UITextField *serialNumberField;
__weak IBOutlet UITextField *valueField;
__weak IBOutlet UILabel *dateLabel;
__weak IBOutlet UIImageView *imageView;

UIPopoverController *imagePickerPopover;

}

  • (id)initForNewItem:(BOOL)isNew;

@property (nonatomic, strong) BNRItem *item;
@property (nonatomic, copy) void (^dismissBlock)(void);

  • (IBAction)backgroundTapped:(id)sender;

  • (IBAction)takePicture:(id)sender;

@end[/code]

DetailViewController.m

[code]#import “DetailViewController.h”
#import “BNRItem.h”
#import “BNRImageStore.h”
#import “BNRItemStore.h”

@interface DetailViewController ()

@end

@implementation DetailViewController
@synthesize dismissBlock;

@synthesize item;

  • (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)bundle
    {
    @throw [NSException exceptionWithName:@“Wrong initializer” reason:@“Use initForNewItem” userInfo:nil];
    return nil;
    }

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

  • (void)viewDidLoad
    {
    [super viewDidLoad];
    UIColor *clr = nil;
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
    clr = [UIColor colorWithRed:0.875 green:0 blue:0.91 alpha:1];
    } else {
    clr = [UIColor groupTableViewBackgroundColor];
    }
    [[self view] setBackgroundColor:clr];
    }

  • (void)viewWillAppear:(BOOL)animated
    {
    [super viewWillAppear];

    [nameField setText:[item itemName]];
    [serialNumberField setText:[item serialNumber]];
    [valueField setText:[NSString stringWithFormat:@"%d", [item valueInDollars]]];

    // Create a NSDateFormatter that will turn a date into a simple date string
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateStyle:NSDateFormatterMediumStyle];
    [dateFormatter setTimeStyle:NSDateFormatterNoStyle];

    // Use filtered NSDate object to see dateLabel contents
    [dateLabel setText:[dateFormatter stringFromDate:[item dateCreated]]];

    NSString *imageKey = [item imageKey];

    if (imageKey) {
    // Get image for image key from image store
    UIImage *imageToDisplay =
    [[BNRImageStore sharedStore] imageForKey];
    // Use that image to put on the screen in imageView
    [imageView setImage:imageToDisplay];
    } else {
    // Clear the imageView
    [imageView setImage:nil];
    }
    }

  • (void) viewWillDisappear:(BOOL)animated
    {
    [super viewWillDisappear];

    // Clear first responder
    [[self view] endEditing:YES];

    // “Save” changes to item
    [item setItemName:[nameField text]];
    [item setSerialNumber:[serialNumberField text]];
    [item setValueInDollars:[[valueField text] intValue]];
    }

  • (void)setItem:(BNRItem *)i
    {
    item = i;
    [[self navigationItem] setTitle:[item itemName]];
    }

  • (IBAction)backgroundTapped:(id)sender
    {
    [[self view] endEditing:YES];
    }

  • (IBAction)takePicture:(id)sender
    {
    if ([imagePickerPopover isPopoverVisible]) {
    // If the popover is already up, get rid of it
    [imagePickerPopover dismissPopoverAnimated:YES];
    imagePickerPopover = nil;
    return;
    }

    NSString *oldKey = [item imageKey];
    // Did the item already have an image?
    if (oldKey) {
    // Delete the old image
    [[BNRImageStore sharedStore] deleteImageForKey:oldKey];
    }

    UIImagePickerController *imagePicker =
    [[UIImagePickerController alloc] init];

    // If our device has a camera, we want to take a picture, otherwise, we
    // just pick from photo library
    if ([UIImagePickerController
    isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
    [imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
    } else {
    [imagePicker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
    }
    // This line of code will generate a warning right now, ignore it
    [imagePicker setDelegate:self];

    // Place image picker on the screen
    // Check for iPad device before instantiating the popover controller
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
    // Create a new popover controller that will display the imagePicker
    imagePickerPopover = [[UIPopoverController alloc] initWithContentViewController:imagePicker];

      [imagePickerPopover setDelegate:self];
      
      // Display the popover controller; sender
      // is the camera bar button item
      [imagePickerPopover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
    

    } else {
    [self presentViewController:imagePicker animated:YES completion:nil];
    }
    }

  • (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
    {
    NSLog(@“User dismissed popover”);
    imagePickerPopover = nil;
    }

  • (void)imagePickerController:(UIImagePickerController *)picker
    didFinishPickingMediaWithInfo:(NSDictionary *)info
    {
    // Get picked image from info dictionary
    UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];

    // Create a CFUUID object - it knows how to create unique identifier strings
    CFUUIDRef newUniqueID = CFUUIDCreate(kCFAllocatorDefault);

    // Create a string from unique identifier
    CFStringRef newUniqueIDString =
    CFUUIDCreateString(kCFAllocatorDefault, newUniqueID);

    // Use that unique ID to set our item’s imageKey
    NSString *key = (__bridge NSString *)newUniqueIDString;
    [item setImageKey:key];

    // Store image in the BNRImageStore with this key
    [[BNRImageStore sharedStore] setImage:image
    forKey:[item imageKey]];

    CFRelease(newUniqueIDString);
    CFRelease(newUniqueID);

    // Put that image onto the screen in out image view
    [imageView setImage:image];

    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
    // If on the phone, the image picker is presented modally. Dismiss it.
    [self dismissViewControllerAnimated:YES completion:nil];
    } else {
    // If on the pad, the image picker is in the popover. Dismiss the popover.
    [imagePickerPopover dismissPopoverAnimated:YES];
    imagePickerPopover = nil;
    }
    }

  • (BOOL)textFieldShouldReturn:(UITextField *)textField
    {
    [textField resignFirstResponder];
    return YES;
    }

  • (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)io
    {
    if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
    return YES;
    } else {
    return (io == UIInterfaceOrientationPortrait);
    }
    }

  • (id)initForNewItem:(BOOL)isNew
    {
    self = [super initWithNibName:@“DetailViewController” bundle:nil];

    if (self) {
    if (isNew) {
    UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(save:)];
    [[self navigationItem] setRightBarButtonItem];

          UIBarButtonItem *cancelItem = [[UIBarButtonItem alloc]
                                         initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancel:)];
          [[self navigationItem] setLeftBarButtonItem:cancelItem];
      }
    

    }

    return self;
    }

  • (IBAction)save:(id)sender
    {
    [[self presentingViewController] dismissViewControllerAnimated:YES completion:dismissBlock];
    }

  • (IBAction)cancel:(id)sender
    {
    // If the user cancelled, then remove the BNRItem from the store
    [[BNRItemStore sharedStore] removeItem:item];

    [[self presentingViewController] dismissViewControllerAnimated:YES completion:dismissBlock];
    }

@end[/code]


#2

In addition to the code, some log excerpt would be useful to identify the problem.


#3

This is what it is saying when i run it sorry after I posted this i gave up…[code]#import <UIKit/UIKit.h>

#import “HomepwnerAppDelegate.h”

int main(int argc, char *argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([HomepwnerAppDelegate class]));
}
}[/code]

this is what output says
2014-04-08 12:43:24.720 Homepwner[1257:907] -[BNRItemStore itemArchivePath]: unrecognized selector sent to instance 0x907c910
2014-04-08 12:43:24.723 Homepwner[1257:907] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[BNRItemStore itemArchivePath]: unrecognized selector sent to instance 0x907c910’
*** First throw call stack:
(0x1c9c012 0x10d9e7e 0x1d274bd 0x1c8bbbc 0x1c8b94e 0x53d7 0x52c8 0x36b2 0x202548 0x205224 0xc9952 0xc92dc 0xccdd6 0xd1a7e 0x6e2dd 0x10ed6b0 0x2298fc0 0x228d33c 0x2298eaf 0x10d2bd 0x55b56 0x5466f 0x54589 0x537e4 0x5361e 0x543d9 0x572d2 0x10199c 0x4e574 0x4e76f 0x4e905 0x57917 0x2f0f 0x1b157 0x1b747 0x1c94b 0x2dcb5 0x2ebeb 0x20698 0x1bf7df9 0x1bf7ad0 0x1c11bf5 0x1c11962 0x1c42bb6 0x1c41f44 0x1c41e1b 0x1c17a 0x1dffc 0x2b3d 0x2a65)
libc++abi.dylib: terminate called throwing an exception
(lldb)


#4

Mangled method name:

[quote][code]
@implementation BNRItemStore

  • (NSString *)itemAchrivePath
    {

    }

    @end
    [/code][/quote]That should be:
@implementation BNRItemStore
...
- (NSString *)itemArchivePath
{
    ...
}
...
@end

The error message contains an important clue:

[quote]… -[BNRItemStore itemArchivePath]: [color=#FF0000]unrecognized selector[/color] sent to instance 0x907c910
… Homepwner[1257:907] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[BNRItemStore itemArchivePath]: [color=#FF0000]unrecognized selector[/color] sent to instance 0x907c910’[/quote]


#5

What code do i put that in and where??
Im sorry I’m so confused and I don’t want to start over… :confused:


#6

BNRItemStore.h and BNRItemStore.m.

BNRItemStore.h

...
@interface BNRItemStore : NSObject
...
- (NSString *)itemArchivePath;
...
@end

BNRItemStore.m

...
@implementation BNRItemStore
...
- (NSString *)itemArchivePath
{
   ...
}
...
@end

#7

ok I see but
BNRItemStore.h

[code]#import <Foundation/Foundation.h>

@class BNRItem;

@interface BNRItemStore : NSObject
{
NSMutableArray *allItems;
}
// Notice that this is a class method and prefixed whit a + instead of a -

  • (BNRItemStore *)sharedStore;
  • (void)removeItem:(BNRItem *)p;

  • (NSArray *)allItems;

  • (BNRItem *)createItem;

  • (void)moveItemAtIndex:(int)from
    toIndex:(int)to;

- (NSString *)itemArchivePath;

  • (BOOL)saveChanges;
    @end
    [/code]

BNRItemStore.m

[code]#import “BNRItemStore.h”
#import “BNRItem.h”

@implementation BNRItemStore

  • (BNRItemStore *)sharedStore
    {
    static BNRItemStore *sharedStore = nil;
    if (!sharedStore)
    sharedStore = [[super allocWithZone:nil] init];

    return sharedStore;
    }

  • (id)allocWithZone:(NSZone *)zone
    {
    return [self sharedStore];
    }

  • (id)init
    {
    self = [super init];
    if (self) {
    NSString *path = [self itemArchivePath];
    allItems = [NSKeyedUnarchiver unarchiveObjectWithFile:path];

      // If the array hadn't been saved previously, create a new empty one
      if (!allItems)
          allItems = [[NSMutableArray alloc] init];
    

    }

    return self;
    }

  • (NSArray *)allItems
    {
    return allItems;
    }

  • (BNRItem *)createItem
    {
    BNRItem *p = [BNRItem randomItem];

    [allItems addObject:p];

    return p;
    }

  • (void)removeItem:(BNRItem *)p
    {
    [allItems removeObjectIdenticalTo:p];
    }

  • (void)moveItemAtIndex:(int)from toIndex:(int)to
    {
    if (from == to) {
    return;
    }
    // Get pointer to object being moved do we can re-insert it
    BNRItem *p = [allItems objectAtIndex:from];

    // Remove p from array
    [allItems removeObjectAtIndex:from];

    // Insert p in array at new location
    [allItems insertObject:p atIndex:to];

}

- (NSString *)itemAchrivePath
{
NSArray *documentDirectories =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

// Get one and only document directory from that list
NSString *documentDirectory = [documentDirectories objectAtIndex:0];

return [documentDirectory stringByAppendingPathComponent:@"items.archive"];

}

  • (BOOL)saveChanges
    {
    // returns success or failure
    NSString *path = [self itemArchivePath];

    return [NSKeyedArchiver archiveRootObject:allItems
    toFile:path];
    }
    @end
    [/code]
    they are Bolded and i had them in there and it still didn’t work??