UITableView + UINavigationController = нераспознанный селектор отправлен в экземпляр xxxxxxxx? - PullRequest
0 голосов
/ 14 февраля 2010

Я создаю приложение, которое использует UINavigationController (перо вида RootViewController.xib), расположенное в MainWindow.xib, и UITableView в RootViewController.xib. У меня есть этот код:

MainWindow.xib's UINavigationController

извините, вам нужно, чтобы увидеть это изображение http://img42.imageshack.us/img42/9338/schermafbeelding2010021.png

TDAppDelegate.h

@interface TDAppDelegate : NSObject <UIApplicationDelegate> {
    // VARIABLES
    NSManagedObjectModel *managedObjectModel;
    NSManagedObjectContext *managedObjectContext;       
    NSPersistentStoreCoordinator *persistentStoreCoordinator;

    // IBOUTLETS
    UIWindow *window;
    UINavigationController *navigationController;
}

// PROPERTIES
@property(nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
@property(nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
@property(nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;

@property(nonatomic, retain) IBOutlet UIWindow *window;
@property(nonatomic, retain) IBOutlet UINavigationController *navigationController;


// IBACTIONS


// METHODS
- (NSString *)applicationDocumentsDirectory;

@end

TDAppDelegate.m

#import "TDAppDelegate.h"


@implementation TDAppDelegate

@synthesize window;
@synthesize navigationController;

// MEMORY
- (void)dealloc {
    [managedObjectContext release];
    [managedObjectModel release];
    [persistentStoreCoordinator release];

    [navigationController release];
    [window release];
    [super dealloc];
}

// APPLICATION

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    [window makeKeyAndVisible];
    [window addSubview:[navigationController view]]; // IT GOES WRONG WHEN I DO THIS
}

- (void)applicationWillTerminate:(UIApplication *)application {
    // Save changes before quitting =D
    NSError *error = nil;
    if(managedObjectContext != nil) {
        if([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        } 
    }
}

// CORE DATA
- (NSManagedObjectContext *) managedObjectContext {
    // Returns the managed object context for the application. If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
    if(managedObjectContext != nil) {
        return managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if(coordinator != nil) {
        managedObjectContext = [[NSManagedObjectContext alloc] init];
        [managedObjectContext setPersistentStoreCoordinator: coordinator];
    }
    return managedObjectContext;
}

- (NSManagedObjectModel *)managedObjectModel {
    // Returns the managed object model for the application. If the model doesn't already exist, it is created by merging all of the models found in the application bundle.
    if(managedObjectModel != nil) {
        return managedObjectModel;
    }
    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];    
    return managedObjectModel;
}

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    // Returns the persistent store coordinator for the application. If the coordinator doesn't already exist, it is created and the application's store added to it.
    if (persistentStoreCoordinator != nil) {
        return persistentStoreCoordinator;
    }

    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"To_Do.sqlite"]];

    NSError *error = nil;
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if(![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        UIAlertView *quitAlert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"error", @"error")  message:[NSString stringWithFormat:NSLocalizedString(@"persistentstorecoordinator error", @""), [error userInfo]] delegate:nil cancelButtonTitle:nil otherButtonTitles:nil];
        [quitAlert show];
        [quitAlert release];
    }    

    return persistentStoreCoordinator;
}


- (NSString *)applicationDocumentsDirectory {
    // Returns the path to the application's Documents directory.
    return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}

@end

TDRootViewController.h

#import <UIKit/UIKit.h>


@interface TDRootViewController : UITableViewController <UITableViewDataSource> {
    NSMutableArray *todoArray;
    NSManagedObjectContext *managedObjectContext;

    UIBarButtonItem *addButton;
}

@property(nonatomic, retain) NSMutableArray *todoArray;
@property(nonatomic, retain) NSManagedObjectContext *managedObjectContext;

@property(nonatomic, retain) UIBarButtonItem *addButton;

@end

TDRootViewController.m

#import "TDRootViewController.h"
#import "TodoItem.h"


@implementation TDRootViewController

// MEMORY
- (void)dealloc {
    [super dealloc];
}

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

- (void)viewDidUnload {
}

// VIEW
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    if(interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
        return YES;
    }
    return NO;
}

// TABLE VIEW

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


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 1;
}


// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // Set up the cell...

    return cell;
}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // Navigation logic may go here. Create and push another view controller.
    // AnotherViewController *anotherViewController = [[AnotherViewController alloc] initWithNibName:@"AnotherView" bundle:nil];
    // [self.navigationController pushViewController:anotherViewController];
    // [anotherViewController release];
}


/*
// 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:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
    }   
    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;
}
*/

// METHODS
- (void)addItem {
    TodoItem *todoItem = (TodoItem *)[NSEntityDescription insertNewObjectForEntityForName:@"TodoItem" inManagedObjectContext:managedObjectContext];
}

@end

фу = D

Хорошо, мое приложение компилируется правильно, но когда оно запускается, святая Консоль говорит следующее:

[Session started at 2010-02-14 14:40:12 +0100.]
2010-02-14 14:40:15.245 To Do[1478:207] *** -[UIViewController tableView:numberOfRowsInSection:]: unrecognized selector sent to instance 0x3a155b0
2010-02-14 14:40:15.246 To Do[1478:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[UIViewController tableView:numberOfRowsInSection:]: unrecognized selector sent to instance 0x3a155b0'
2010-02-14 14:40:15.246 To Do[1478:207] Stack: (
    30893147,
    2500113673,
    31275067,
    30844534,
    30697154,
    4364410,
    4371786,
    4370783,
    3087322,
    3027833,
    3069268,
    3057823,
    57406128,
    57405551,
    57403590,
    57402682,
    2731769,
    2755464,
    2737875,
    2764981,
    38989521,
    30677888,
    30673992,
    2731625,
    2768899,
    10592,
    10446
)

Я думаю, что это как-то связано с numberOfRowsInSection, но я не уверен. Может кто-нибудь мне помочь? Спасибо

Ответы [ 2 ]

1 голос
/ 14 февраля 2010

Я полагаю, что вы подключили соединение источника данных проблемного UITableView (в Интерфейсном Разработчике) с неверным источником.
Он должен быть подключен к владельцу файла.

Или класс владельца файла не установлен на правильный контроллер представления.

Разместите несколько скриншотов с вашего IB.
Опубликовать следующие экраны:
- выберите вид таблицы и нажмите Cmd + 2
- выберите владельца файла и нажмите Cmd + 4

0 голосов
/ 15 февраля 2010

Вы правы, это как-то связано с методом -tableView:numberOfRowsInSection:, поэтому ошибка упоминает этот метод специально.

Этот метод является одним из методов источника данных табличного представления. Сообщение «нераспознанный селектор» означает, что табличное представление пытается вызвать этот метод для объекта, который его не реализует. Поскольку вы реализовали этот метод в TDRootViewController, вы должны подключить источник данных к чему-то другому.

Я не думаю, что у нас достаточно информации, чтобы сказать, где он подключен , но он явно подключен неправильно. Посмотри в ИБ, найди эту связь и посмотри, куда она ведет. Затем исправьте его так, чтобы он указывал на правильное место, которое, по-видимому, будет вашим экземпляром TDRootViewController.

...