【问题标题】:Unrecognized selector sent to instance and crash无法识别的选择器发送到实例并崩溃
【发布时间】:2014-10-03 22:50:32
【问题描述】:

我正在使用 xcode 中的情节提要,并且在 prepareForSegue 方法期间它崩溃了。我想要做的是在我单击一个单元格后从一个表格视图进入另一个详细的表格视图。这是代码。

GamesInfoViewController.m

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([[segue identifier] isEqualToString:@"ShowDetails"]) {
    DetailViewController2 *detailViewController = [segue destinationViewController];

    NSIndexPath *myIndexPath = [self.tableView indexPathForSelectedRow];

    NSUInteger row = [myIndexPath row];
    GameInfo *gameInfoObject;

    gameInfoObject =[GamesInfoArray objectAtIndex:row];
    detailViewController.DetailArray = @[gameInfoObject.HomeTeam, gameInfoObject.AwayTeam];  // IT CRASHES HERE!!!
}

}

这里是 DetailViewController2.m

- (void)viewDidLoad {
[super viewDidLoad];

// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;

// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;

[self.tableView reloadData];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
GamesInfoTableViewCell *cell = (GamesInfoTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"MainCell"];

cell.mainLabel.text = _DetailArray[0];
cell.awayTeamLabel.text = _DetailArray[1];

// Configure the cell...

return cell;

}

DetailViewController2.h

#import <UIKit/UIKit.h>

@interface DetailViewController2 : UITableViewController

@property (strong, nonatomic) NSArray *DetailArray;
@end

是的,我已选择 DetailViewController2 作为故事板中的自定义类!!!

错误消息:'NSInvalidArgumentException',原因:'-[UINavigationController setDetailArray:]: unrecognized selector sent to instance 0x7fa65a537f00'

【问题讨论】:

  • 请发布无法识别的选择器。
  • 请发布您收到的错误消息。
  • 添加到问题底部!
  • DetailViewController2 是 UINavigationController 的子类还是嵌入在 UINavigationController 中?
  • 它是一个子类,有关系吗?

标签: ios objective-c uitableview selector uistoryboardsegue


【解决方案1】:

好像是这条线

DetailViewController2 *detailViewController = [segue destinationViewController];

返回 UINavigationController 而不是 DetailViewController2

如果 DetailViewController2 嵌入在 UINavigationController 中,您可能想要执行以下操作:

UINavigationController *navController = [segue destinationViewController];
DetailViewController2 *detailViewController = (DetailViewController2  *)navController.topViewController;

如果DetailViewController2 是UINavigationController 的子类,您可能忘记在情节提要中明确说明。

【讨论】:

  • 它适用于您的代码,但它给了我一个错误,为什么会这样?使用“UIViewController *”类型的表达式初始化“DetailViewController2 *”的不兼容指针类型@KIDdAe
  • 我编辑了我的答案以删除此警告。你明白了,因为编译器知道 navController.topViewController 是 UIViewController,但此时它不能确定它也是 DetailViewController2,所以它警告你这里可能有错误。
  • 工作就像一个魅力!再次感谢。
【解决方案2】:

KIDdAes 完全正确 DetailViewController2 *detailViewController = [segue destinationViewController]; 返回的是 UINavigationController 而不是 DetailViewController2 我的答案更多的是清理您现有的代码,我也会添加答案。

GamesInfoViewController.m

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"ShowDetails"]) {
        // [segue returns a UINavigationController and the controller you 
        // want is embedded in the navigation controller
        UINavigationController *navigationController = [segue destinationViewController];

        // We want the top view controller from the navigationController
        // and don't forget the cast
        DetailViewController2 *detailViewController = (DetailViewController2 *)navigationController.topViewController;



        // Removed redundant line as there was no need to create local variable for
        // one time use
        NSUInteger row = [[self.tableView indexPathForSelectedRow] row];

        // There was no need to have these two on on separate lines
        GameInfo *gameInfoObject = [GamesInfoArray objectAtIndex:row];

        // To add a fail safe you could wrap this in respondsToSelector
        // just in the event that the topViewController isn't a DetailViewController2 
        if ([detailViewController respondsToSelector:@selector(setDetailArray:)]) {
            // Note the lowercase for detailArray see comments above this property.
            detailViewController.detailArray = @[gameInfoObject.HomeTeam, gameInfoObject.AwayTeam];  
        }
    }
}

DetailViewController2.h

#import <UIKit/UIKit.h>

@interface DetailViewController2 : UITableViewController

// Properties and ivars start with lowercases classes have uppercases
// try to stay to coding conventions it will help you and others when needing help
@property (strong, nonatomic) NSArray *detailArray;

@end

DetailViewController2.m

- (void)viewDidLoad 
{
    [super viewDidLoad];

    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;

    [self.tableView reloadData];
 }


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
   GamesInfoTableViewCell *cell = (GamesInfoTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"MainCell"];

   cell.mainLabel.text = _detailArray[0];
   cell.awayTeamLabel.text = _detailArray[1];

   // Configure the cell...

   return cell;
}

如果您阅读答案中的 cmets,您会明白为什么我将事情变得更好。如果您有任何问题,请提出。

【讨论】:

  • 美丽 :),感谢您评论您为什么这样做。只是一个可能与您的代码无关的问题,但如果我有另一个 tableview 将显示与 DetailViewController2 完全相同的内容。我是否必须使用与 DetailViewController2 相同的 tableview 制作另一个导航控制器,或者我可以将它连接到同一个类?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多