2

Big Nerd Ranch iOS Programming 3rd edition を使用していますが、シングルトンであるセレクター 'defaultStore' で問題が発生しました。エラーは、そのようなクラスメソッドが存在しないことを示しており、コメントアウトした問題を修正する方法がわかりません。

コアデータに切り替わる部分もあると思いますが、まだその部分には至っていません。

ItemsViewController.m

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

@implementation ItemsViewController
- (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;
}

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


- (IBAction)addNewItem:(id)sender
{
  // Create a new BNRItem and add it to the store
  BNRItem *newItem = [[BNRItemStore defaultStore] createItem];//No known class method for selector 'defaultStore'
  // Incompatible pointer types initializing 'BNRItem*__strong' with an expression of 'NSArray'

  // Figure out where that item is in the array 
  int lastRow = [[[BNRItemStore defaultStore] allItems] indexOfObject:newItem]; //No known class method for selector 'defaultStore'

  NSIndexPath *ip = [NSIndexPath indexPathForRow:lastRow inSection:0];

  // Insert this new row into the table.
  [[self tableView] insertRowsAtIndexPaths:[NSArray arrayWithObject:ip]
                          withRowAnimation:UITableViewRowAnimationTop];
}  
- (id)initWithStyle:(UITableViewStyle)style
{
  return [self init];
}

- (void)tableView:(UITableView *)tableView 
moveRowAtIndexPath:(NSIndexPath *)fromIndexPath 
      toIndexPath:(NSIndexPath *)toIndexPath 
{
  [[BNRItemStore defaultStore] moveItemAtIndex:[fromIndexPath row] //No known class method for selector 'defaultStore'
                                       toIndex:[toIndexPath row]];
}

- (void)tableView:(UITableView *)aTableView 
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
  DetailViewController *detailViewController = [[DetailViewController alloc] init];

  NSArray *items = [[BNRItemStore defaultStore] allItems];//No known class method for selector 'defaultStore'
  BNRItem *selectedItem = [items objectAtIndex:[indexPath row]];

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

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

- (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 defaultStore];//No known class method for selector 'defaultStore'
    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];
  }
}

- (NSInteger)tableView:(UITableView *)tableView
 numberOfRowsInSection:(NSInteger)section
{
  return [[[BNRItemStore defaultStore] allItems] count];//No known class method for selector 'defaultStore'
}
- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  // Create an instance of UITableViewCell, with default appearance
  // Check 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 defaultStore] allItems]//No known class method for selector 'defaultStore'
                objectAtIndex:[indexPath row]];
  [[cell textLabel] setText:[p description]];
  return cell;
}
@end

BNRItemStore.h

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

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
4

1 に答える 1

4

(BNRItemStore.h 内の)の@interfaceブロックがそのメソッドを宣言していることを確認してください。BNRItemStore

@interface BNRItemStore : NSObject

+ (BNRItemStore *)defaultStore;

// etc.

@end

コンパイラはインターフェイスを調べて、そのクラスで使用できるメソッドを認識します。

于 2012-04-30T23:01:26.510 に答える