UITableView + UINavigationController = 无法识别的选择器发送到实例 xxxxxxxx?

发布于 2024-08-21 16:03:32 字数 9651 浏览 4 评论 0原文

我正在创建一个应用程序,它使用位于 MainWindow.xib 中的 UINavigationController (其视图的笔尖是 RootViewController.xib)和位于 MainWindow.xib 中的 UITableView RootViewController.xib。 我有这个代码:

MainWindow.xib的 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

phew =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 有关,但我不确定。有人可以帮我吗?谢谢

I'm creating an app which uses a UINavigationController (which's view's nib is RootViewController.xib) located in MainWindow.xib, and a UITableView in RootViewController.xib.
I have this code:

MainWindow.xib's UINavigationController

sorry, you need to be able to see this image 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

phew =D

Okay, my app compiles correctly, but when it starts, the holy Console says this:

[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
)

I think it has something to do with numberOfRowsInSection but I'm not sure. Can anyone help me out? Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

弥枳 2024-08-28 16:03:32

我相信您已将有问题的 UITableView(在 Interface Builder 中)的数据源连接连接到错误的源。

它应该连接到文件的所有者。

或者文件所有者的类未设置为正确的视图控制器。

发布一些您 IB 的屏幕截图。

发布下一个屏幕:

- 选择表格视图并按 Cmd+2

- 选择文件的所有者并按 Cmd+4

I believe that you've connected the datasource's connection of the problematic UITableView (in Interface Builder) to wrong source.

It should be connected to file's owner.

Or the class of file's owner is not set to the correct view controller.

Post some screenshots from your IB.

Post the next screens:

- select the table view and press Cmd+2

- select the file's owner and press Cmd+4

只等公子 2024-08-28 16:03:32

你是对的,它确实与 -tableView:numberOfRowsInSection: 方法有关,这就是错误特别提到该方法的原因。

该方法是表视图的数据源方法之一。 “无法识别的选择器”消息意味着表视图正在尝试在未实现该方法的对象上调用此方法。由于您在 TDRootViewController 中实现了该方法,因此您必须将数据源连接到其他东西。

我认为我们没有足够的信息来说明它的连接位置,但它显然连接错误。看看IB,找到这个联系,看看它通向哪里。然后修复它,使其指向正确的位置,该位置似乎是您的 TDRootViewController 实例。

You're right, it does have something to do with the -tableView:numberOfRowsInSection: method, that's why the error mentions that method specifically.

That method is one of the table view's data source methods. The "unrecognized selector" message means that the table view is attempting to call this method on an object that doesn't implement it. Since you implemented that method in TDRootViewController, you must have connected the data source to something else.

I don't think we have enough information to say where it is connected, but it's clearly connected wrongly. Look in IB, find this connection, and see where it leads. Then fix it so that it points to the right place, which would appear to be your instance of TDRootViewController.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文