1

有一个 BNRItemStore 的单例类,但是当我尝试调用它时,我得到了导致 ARC 问题的上述错误。已将错误注释掉。

细节视图控制器.m

#import "DetailViewController.h"
#import "BNRItem.h"
#import "BNRImageStore.h"
#import "BNRItemStore.h"



@implementation DetailViewController
@synthesize item;

-(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:doneItem];

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

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

-(void)viewDidLoad
{
  [super viewDidLoad];

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

- (void)viewDidUnload {
  nameField = nil;
  serialNumberField = nil;
  valueField = nil;
  dateLabel = nil;
  imageView = nil;
  [super viewDidUnload];
}

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

  [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 set 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:imageKey];

    // 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:animated];

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

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

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

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

- (IBAction)takePicture:(id)sender {

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

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

  // If our device has a camera, we want to take a picture, otherwise, we
  // just pick from the 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;
}

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

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
  NSString *oldKey = [item imageKey];

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

  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); // Incompatible integer to pointer conversion initializing 

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

  [imageView setImage:image];

  if ([[UIDevice currentDevice]userInterfaceIdiom]==UIUserInterfaceIdiomPad) {
    // 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;
}

-(void)save:(id)sender
{
  [[self presentingViewController]dismissViewControllerAnimated:YES 
                                                     completion:nil];
}

-(void)cancel:(id)sender
{
  // If the user cancelled, then remove the BNRItem from the store
  [[BNRItemStore sharedStore]removeItem:item]; // No known class method for selector 'sharedStore'

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

DetailViewController.h

#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;
}
@property(nonatomic,strong)BNRItem *item;

-(id)initForNewItem:(BOOL)isNew;

- (IBAction)takePicture:(id)sender;

- (IBAction)backgroundTapped:(id)sender;
@end

BNRItemStore.m

#import "BNRItemStore.h"
#import "BNRItem.h"


@implementation BNRItemStore

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

  return defaultStore;
}

+ (id)allocWithZone:(NSZone *)zone
{
  return [self defaultStore];
}

- (id)init 
{
  self = [super init];
  if(self) {
    allItems = [[NSMutableArray alloc] init];
  }
  return self;
}

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

- (NSArray *)allItems
{
  return allItems;
}

- (void)moveItemAtIndex:(int)from
                toIndex:(int)to
{
  if (from == to) {
    return;
  }
  // Get pointer to object being moved so 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];
}

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

  [allItems addObject:p];

  return p;
}
@end

BNRItemStore.h

#import <Foundation/Foundation.h>
@class BNRItem;

@interface BNRItemStore : NSObject
{
  NSMutableArray *allItems;
}

+ (BNRItemStore *)defaultStore;

- (void)removeItem:(BNRItem *)p;

- (NSArray *)allItems;

- (BNRItem *)createItem;

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

@end
4

1 回答 1

1

您正在调用错误发生+sharedStore的位置。BNRItemStore这是因为根据您发布的代码,它确实不存在。

所有其他呼叫都在使用您未提供+sharedStore的大概可用的电话。BNRImageStore我认为它存在于那个类中?:)

简而言之,改变:

[[BNRItemStore sharedStore]removeItem:item];

[[BNRImageStore sharedStore]removeItem:item];
于 2012-05-02T18:30:35.997 回答