iPhone: IBAction вызывает ошибку «Неопознанный селектор отправлен в экземпляр» - PullRequest
2 голосов
/ 20 февраля 2010

Я работаю над своим первым настоящим приложением для 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 имеет свой эталонный выход как IBOutlet в SwitchViewController.

Так вот .h для 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;  

А для функции 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 ]

12 голосов
/ 16 декабря 2010

Мы просто столкнулись с той же проблемой. Кажется, мы выпустили объект ViewController в AppDelegate, а затем наше представление nib попыталось вызвать IBAction (на контроллере представления). Половину времени мы получали «EXC_BAD_ACCESS» (он же отправлял сообщения об освобожденном объекте), и половину времени мы получали «нераспознанный селектор, отправленный на экземпляр» NSCFString, NSCFArray, всевозможные вещи (то есть обмен сообщениями в области памяти, которая теперь занята) другим объектом).

Просто убедитесь, что ваш ViewController еще не выпущен.

4 голосов
/ 21 февраля 2010

Хорошо, мне указали решение. Надо было направить его через FirstResponder (я ... действительно не понимаю, почему это работает, но на данный момент я просто счастлив, что это работает.)

В любом случае, я не уверен, как работает первый респондент (ни одна из книг, о которых я упоминал), но это ... работает? Если кто-то хочет дать мне краткое изложение, это было бы полезно ... но на этот вопрос был дан ответ.

0 голосов
/ 25 ноября 2014

Проблема в том, что вы инициировали экземпляр 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...
}
0 голосов
/ 05 февраля 2013

К вашему сведению, я получал это при использовании ARC, когда xib загружался и выводился на экран, но почему-то сам VC не сохранялся.

Я решил это, добавив переменную для хранения ссылки в VC, который ее представлял.

0 голосов
/ 08 января 2012

Правильный ответ таков:

Контроллер представления, который мы назначаем в качестве первого экрана в делегате приложения, не должен освобождаться в методе - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions. В вашем случае первый экран MainScreenViewController.

Он (MainScreenViewController экземпляр) должен быть освобожден в методе делегата приложения dealloc.

- (void)dealloc
{
    [_window release];
    [mainScreenViewController release];
    [super dealloc];
}
0 голосов
/ 07 января 2012

Это также может помочь.Процедура Analyzer порекомендовала мне выпустить несколько объектов, и я это сделал.Оказывается, мне нужны эти объекты в приложении.В файле xAppDelegate.m (или в любом другом) в методе / сообщении / функции / процедуре / вещи appDidFinishLaunching используйте

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

вместо

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

Кроме того, рекомендуется анализаторЯ отпускаю объект, который я нажал на навигационный контроллер.Большая ошибка.Этим файлом был экран моего меню, и когда я нажал кнопку, я получил unrecognized selector sent to instance.По-видимому, он звонил IBAction на NSString и NSDictionary, что нехорошо.

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

Я предполагаю, что проблема в вашем файле пера.

Ошибка означает, что после нажатия кнопки она пытается отправить сообщение / вызов метода switchView объекту NSDictionary, который, разумеется, не имеет такого метода. Ошибка заключается в том, где указано действие кнопок.

Проверьте перо для этого представления. Посмотрите на владельца файла и проверьте присвоенный ему класс. Убедитесь, что это SwitchViewController, а не словарь по некоторым причинам. Если для свойства «Владелец файла» задан класс словаря, он загрузит словарь и попытается отправить ему метод действия.

...