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

发布于 2024-08-21 22:37:48 字数 2648 浏览 9 评论 0原文

我正在开发我的第一个真正的 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];
 }
}

简而言之,我完全迷失了,这真的很令人沮丧。有人有任何建议,或者需要更多代码吗?

I'm working on my first real iPhone app, a simple To-Do list application to help me organize stuff, except I'm getting an "unrecognized selector sent to instance 0x".

Specifically:

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'

I've looked around and figured out that it might be a connection problem in IB, but I'm new to this whole connecting thing (man, I wish they supported Java or Python), so here's how it's laid out. I've got 3 classes, a SwitchViewController, a MainScreenViewController, and a ToDoListViewController. When I hit a button on MainScreenViewController, I trigger the "switchViews" function that's throwing this problem. They way I've got it set up is that the button (a UIBarButtonItem) has the "sentAction" go to switchViews. This ViewButton has its reference outlet as a IBOutlet in SwitchViewController.

So here's the .h for SVC:

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

And for the switchViews function:

-(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];
 }
}

So in short, I'm totally lost, and this is really frustrating. Anyone have any advice, or need any more code?

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

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

发布评论

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

评论(7

原野 2024-08-28 22:37:48

我们刚刚遇到了同样的问题。看来我们在 AppDelegate 中释放了 ViewController 对象,然后我们的 nib 视图尝试调用 IBAction (在视图控制器上)。有一半的时间我们收到“EXC_BAD_ACCESS”(又名消息传递已释放的对象),一半的时间我们收到“无法识别的选择器发送到 NSCFString、NSCFArray 的实例”,以及各种各样的事情(又名消息传递已占用的内存区域)由不同的对象)。

只需检查您的 ViewController 尚未发布。

We just ran into the same problem. It seems we released the ViewController object in the AppDelegate and then our nib view tried to invoke an IBAction (on the view controller). Half the time we were getting "EXC_BAD_ACCESS" (aka messaging a released object), and half the time we were getting "unrecognized selector sent to instance" of NSCFString, NSCFArray, all sorts of things (aka messaging an area of memory now taken up by a different object).

Just check your ViewController hasn't been released.

此岸叶落 2024-08-28 22:37:48

好的,已经向我指出了解决方案。应该让它通过 FirstResponder 路由(我……真的不明白为什么会起作用,但此时我很高兴它能起作用。)

我不确定 First Responder 是如何工作的(我读过的书都没有)确实提到过),但是它......有效吗?如果有人想给我一个概要,那会很有用......但这个问题已经得到解答。

Okay, got the solution pointed out to me. Should have had it routed through FirstResponder (I ... really don't understand why that works, but at this point I'm just happy it works.)

I'm not sure how first responder works anyways (none of the books I have really mention it), but it... works? If someone wants to give me a rundown, that'd be useful... but this question has been answered.

偏闹i 2024-08-28 22:37:48

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

该错误意味着单击按钮后,按钮会尝试将 switchView 的消息/方法调用发送到 NSDictionary 对象,该对象当然没有此类方法。错误就出在按钮操作所指向的位置。

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

I'm going to guess the problem is in your nib file.

The error means that upon clicking the button, the button tries to send a message/method-call of switchView to an NSDictionary object which of course has no such method. The error then lays in where the buttons action is pointed.

Check the nib for this view. Look at the File Owner and check the class assigned to it. Make sure it is SwitchViewController and not a dictionary for some reason. If the File Owner property is set to a dictionary class it will load a dictionary and try to send the action method it to it.

酷到爆炸 2024-08-28 22:37:48

正确的答案是:

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

它(MainScreenViewController 实例)应在应用程序委托的 dealloc 方法中释放。

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

The right answer is this:

The view controller that we assign as the first screen in the app delegate shouldn't be released in the - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method. In your case the first screen is MainScreenViewController.

It (MainScreenViewController instance)should be released in app delegate's dealloc method.

- (void)dealloc
{
    [_window release];
    [mainScreenViewController release];
    [super dealloc];
}
爱你不解释 2024-08-28 22:37:48

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

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

代替

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

Also,Analyzer建议我释放我推送的对象到导航控制器上。大错误。该文件是我的菜单屏幕,当我按下按钮时,我收到了一个发送到实例的无法识别的选择器。显然,它在 NSStringNSDictionary 上调用 IBAction,这不好。

This might also help. The Analyzer routine recommended I release a few objects, and I did. Turns out, I needed those objects in the app. In the xAppDelegate.m file (or whatever) in the appDidFinishLaunching method/message/function/routine/thing, use

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

instead of

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

Also, Analyzer recommended I release the object I pushed onto the nav controller. Big mistake. That file was my menu screen and when I pressed a button, I received a unrecognized selector sent to instance. Apparently, it was calling IBAction on NSString and NSDictionary, which is not good.

夜血缘 2024-08-28 22:37:48

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

我通过添加一个变量来存储呈现它的 VC 中的引用来解决这个问题。

FYI I was getting this when using ARC and the xib was being loading and put onto the screen, but somehow the VC itself was not being retained.

I solved it by adding a variable to store reference in the VC that was presenting it.

ˉ厌 2024-08-28 22:37:48

问题是,您已将 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...
}

The problem is, you have initiated the UIViewController instance as a method variable. So the view controller have no scope after the execution of the method and so it is released from the memory cycle. So you have to make your view controller instance as class level.

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