iPhone:IBAction导致“无法识别的选择器发送到实例”错误

时间:2010-02-20 19:40:38

标签: iphone interface-builder selector ibaction

我正在开发我的第一个真正的iPhone应用程序,一个简单的待办事项列表应用程序,以帮助我组织东西,除了我得到一个“无法识别的选择器发送到实例0x”。

具体做法是:

2010-02-20 14:30:09.200 ToDoApp[88562:20b] *** -[NSCFDictionary switchViews:]: unrecognized selector sent to instance 0x3d22de0

2010-02-20 14:30:09.201 ToDoApp[88562:20b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSCFDictionary switchViews:]: unrecognized selector sent to instance 0x3d22de0'

我环顾四周,发现它可能是IB中的一个连接问题,但我对这整个连接事物都是新手(男人,我希望他们支持Java或Python),所以这里是如何布局的。我有3个类,一个SwitchViewController,一个MainScreenViewController和一个ToDoListViewController。当我点击MainScreenViewController上的一个按钮时,我触发了“switchViews”函数,这就是抛出这个问题。他们设置的方式是按钮(一个UIBarButtonItem)将“sentAction”转到switchViews。这个ViewButton的参考出口是SwitchViewController中的IBOutlet。

所以这里是SVC的.h:

#import <UIKit/UIKit.h>

@class MainScreenViewController;
@class ToDoListViewController;
@class EditViewController;

#define kMinimumGestureLength 25
#define kMaximumVariance 5

@interface SwitchViewController : UIViewController {
 MainScreenViewController *mainScreenViewController;
 ToDoListViewController *toDoListViewController;
 EditViewController *editViewController;
 IBOutlet UIBarButtonItem *viewButton;
 CGPoint gestureStartPoint;
}

@property (retain, nonatomic) MainScreenViewController *mainScreenViewController;
@property (retain, nonatomic) ToDoListViewController *toDoListViewController;
@property (retain, nonatomic) EditViewController *editViewController;
@property (retain, nonatomic) IBOutlet UIBarButtonItem *viewButton;
@property CGPoint gestureStartPoint;
-(IBAction)switchViews:(id)sender;  

对于switchViews函数:

-(IBAction) switchViews:(id)sender
{
 NSLog(@"Switching views");
 if(self.toDoListViewController.view.superview == nil){
  if(self.toDoListViewController ==nil){
   ToDoListViewController *toDoVC = [[ToDoListViewController alloc]     initWithNibName:@"ToDoListView" bundle:nil];
   self.toDoListViewController = toDoVC;
   //[toDoVC release];
  }
  [mainScreenViewController.view removeFromSuperview];
  [self.view insertSubview:toDoListViewController.view atIndex:0];
 }
 else{
  if(self.mainScreenViewController == nil){
   MainScreenViewController *mainController =     [[MainScreenViewController alloc] initWithNibName:@"MainScreenView" bundle:nil];
   self.mainScreenViewController = mainController;
   //[mainController release];
  }
  [toDoListViewController.view removeFromSuperview];
  [self.view insertSubview:mainScreenViewController.view atIndex:0];
 }
}

所以简而言之,我完全迷失了,这真的令人沮丧。任何人有任何建议,还是需要更多代码?

7 个答案:

答案 0 :(得分:12)

我们遇到了同样的问题。我们似乎在AppDelegate中发布了ViewController对象,然后我们的nib视图尝试调用IBAction(在视图控制器上)。有一半时间我们得到“EXC_BAD_ACCESS”(也就是发布对象的消息),有一半时间我们得到了“无法识别的选择器发送到实例”的NSCFString,NSCFArray,各种各样的东西(也就是消息现在占用的内存区域)由不同的对象)。

请检查您的ViewController尚未发布。

答案 1 :(得分:4)

好的,解决了我的解决方案。本应该通过FirstResponder进行路由(我...真的不明白为什么会有效,但此时我很高兴它有效。)

我不确定第一响应者是如何工作的(没有我真正提到过的书),但它......有效吗?如果有人想给我一个破产,那就有用了......但是这个问题已经得到了回答。

答案 2 :(得分:0)

我猜你的nib文件中存在问题。

错误意味着在单击按钮时,该按钮会尝试向NSDictionary对象发送switchView的消息/方法调用,这当然没有这样的方法。然后该错误位于按钮操作指向的位置。

检查nib是否有此视图。查看文件所有者并检查分配给它的类。由于某种原因,请确保它是SwitchViewController而不是字典。如果File Owner属性设置为字典类,它将加载字典并尝试将action方法发送给它。

答案 3 :(得分:0)

这也可能有所帮助。 Analyzer例程建议我发布一些对象,我做了。事实证明,我在应用程序中需要这些对象。在xAppDelegate.m方法/消息/函数/例程/事物的appDidFinishLaunching文件(或其他)中,使用

UINavigationController *navController = [[UINavigationController alloc] init];

而不是

UINavigationController *navController = [[[UINavigationController alloc] init] autorelease];

此外,Analyzer建议我释放我推送到导航控制器上的对象。大错。该文件是我的菜单屏幕,当我按下按钮时,我收到了unrecognized selector sent to instance。显然,它在IBActionNSString上调用了NSDictionary,这并不好。

答案 4 :(得分:0)

正确的答案是:

我们指定为应用委托中第一个屏幕的视图控制器不应在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法中发布。在您的情况下,第一个屏幕是MainScreenViewController

应该在app delegate的MainScreenViewController方法中发布它(dealloc实例)。

- (void)dealloc
{
    [_window release];
    [mainScreenViewController release];
    [super dealloc];
}

答案 5 :(得分:0)

仅供参考我在使用ARC并且xib正在加载并放到屏幕上时得到了这个,但不知何故VC本身没有被保留。

我通过在VC中添加一个变量来存储引用来解决它。

答案 6 :(得分:0)

问题是,您已将UIViewController实例作为方法变量启动。因此视图控制器在执行方法后没有范围,因此它从内存周期中释放。因此,您必须将视图控制器实例设置为类级别。

  @interface SwitchViewController () {
         ToDoListViewController *toDoVC;
         MainScreenViewController *mainController;
    }



-(IBAction) switchViews:(id)sender
{
     if (!toDoVC)
          toDoVC = [[ToDoListViewController alloc]     initWithNibName:@"ToDoListView" bundle:nil];
     if (!mainController)
          mainController =     [[MainScreenViewController alloc] initWithNibName:@"MainScreenView" bundle:nil];

 //Your stuff with the view controllers...
}