Нераспознанный селектор в NSObject

#ios #nsobject #unrecognized-selector

#iOS #nsobject #нераспознанный селектор

Вопрос:

У меня есть ViewController, который создает экземпляр класса Trophy, чтобы он делал это:

 #import "Trophy.h"
#import "WATrophiesViewController.h"

@implementation Trophy


-(id)initWithFrame:(CGRect)frame trophyName:(NSString *)trophyName trophyDesc:(NSString *)trophyDesc imageName:(NSString *)imageName viewController:(UIViewController *)controller
{
    self = [super init];
    if (self)
    {
        self.view = [[UIView alloc] initWithFrame:frame];
        self.trophyName = trophyName;
        self.trophyDesc = trophyDesc;
        self.trophyImage = imageName;
        self.controller = controller;
    }
    return self;
}

-(UIView *)drawView
{
    // Imposto lo sfondo del frame della view
    self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"container"]];

    // Imposto l'immagine del trofeo
    UIImageView *image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:self.trophyImage]];
    CGRect imageFrame = CGRectMake(0.0f, 0.0f, 138.0f, 191.0f);
    image.frame = imageFrame;

    // La disegno
    [self.view addSubview:image];

    // Imposto il titolo del trofeo
    UILabel *titolo = [[UILabel alloc] initWithFrame:CGRectMake(140.0f, 20.0f, 260.0f, 90.0f)];
    titolo.text = self.trophyName;
    titolo.numberOfLines = 0;
    titolo.lineBreakMode = NSLineBreakByWordWrapping;
    titolo.textColor = [UIColor whiteColor];

    // Lo disegno
    [self.view addSubview:titolo];

    // Imposto la parte per lo share
    UIView *shareDiv = [[UIView alloc] initWithFrame:CGRectMake(140.0f, 130.0f, 300.0f, 140.0f)];
    UILabel *share = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 300.0f, 30.0f)];
    share.text = @"SHARE";
    share.textColor = [UIColor whiteColor];
    [shareDiv addSubview:share];
    UIButton *twitter = [[UIButton alloc] initWithFrame:CGRectMake(0.0f, 30.0f, 40.0f, 40.0f)];
    [twitter setBackgroundImage:[UIImage imageNamed:@"tw-iphone"] forState:UIControlStateNormal];
    [twitter addTarget:self action:@selector(twitter:) forControlEvents:UIControlEventTouchUpInside];
    [shareDiv addSubview:twitter];

    UIButton *fb = [[UIButton alloc] initWithFrame:CGRectMake(50.0f, 30.0f, 40.0f, 40.0f)];
    [fb setBackgroundImage:[UIImage imageNamed:@"fb-iphone"] forState:UIControlStateNormal];
    [fb addTarget:self action:@selector(fb:) forControlEvents:UIControlEventTouchUpInside];
    [shareDiv addSubview:fb];


    [self.view addSubview:shareDiv];

    return self.view;
}

-(void)twitter:(id)sender
{

}
-(void)fb:(id)sender
{

}
@end
  

Но когда я нажимаю на одну из этих двух кнопок, возникают ошибки. Почему? Это ошибка:
Завершение работы приложения из-за неперехваченного исключения ‘NSInvalidArgumentException’, причина: ‘-[__NSArrayM fb:]: нераспознанный селектор, отправленный экземпляру 0x16e9e7d0’

РЕДАКТИРОВАТЬ: это трассировка стека

 2014-06-18 14:02:55.953 Wikitude Approx[1027:60b] (
0   Wikitude Approx                     0x000f5c57 -[Trophy drawView]   1446
1   Wikitude Approx                     0x000f48c9 -[WATrophiesViewController viewDidLoad]   1352
2   UIKit                               0x330f2a53 <redacted>   518
3   UIKit                               0x3319d30d <redacted>   32
4   UIKit                               0x3319d223 <redacted>   230
5   UIKit                               0x3319c801 <redacted>   80
6   UIKit                               0x3319c529 <redacted>   572
7   UIKit                               0x3319c299 <redacted>   44
8   UIKit                               0x3319c231 <redacted>   184
9   UIKit                               0x330ee305 <redacted>   380
10  QuartzCore                          0x32d6a31b <redacted>   142
11  QuartzCore                          0x32d65b3f <redacted>   350
12  QuartzCore                          0x32d659d1 <redacted>   16
13  QuartzCore                          0x32d653e5 <redacted>   228
14  QuartzCore                          0x32d651f7 <redacted>   314
15  UIKit                               0x330e6a27 <redacted>   126
16  CoreFoundation                      0x3088a039 <redacted>   20
17  CoreFoundation                      0x308879c7 <redacted>   286
18  CoreFoundation                      0x30887d13 <redacted>   738
19  CoreFoundation                      0x307f2769 CFRunLoopRunSpecific   524
20  CoreFoundation                      0x307f254b CFRunLoopRunInMode   106
21  GraphicsServices                    0x3575f6d3 GSEventRunModal   138
22  UIKit                               0x33151891 UIApplicationMain   1136
23  Wikitude Approx                     0x000f23e1 main   116
24  libdyld.dylib                       0x3b553ab7 <redacted>   2
  

)

Вот как я использую класс

 self.scroll.contentSize = CGSizeMake(414.0f, 3000.0f);

// Creo il trofeo della prima visita
Trophy *trofeoPrimaVisita = [[Trophy alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 414.0f, 228.0f) trophyName:@"Hai lanciato per la prima volta l'applicazione" trophyDesc:@"Ho lanciato per la prima volta l'applicazione Hermes" imageName:@"trofeoaudio-guida-5" viewController:self];
UIView *trofeoView = [trofeoPrimaVisita drawView];
[self.scroll addSubview:trofeoView];
  

Комментарии:

1. Я не думаю, что ошибка в коде, который вы опубликовали. Пожалуйста, опубликуйте трассировку стека.

2. Похоже, что созданный вами объект Trophy выпущен, вам нужно сохранить на него строгую ссылку.

3. NSInvalidArgumentException', reason: '-[__NSArrayM fb:]: unrecognized selector sent to instance 0x16e9e7d0 по какой-либо причине метод fb вызывается на a NSMutableArray , который, конечно, не реализует метод fb

4. Что WATrophiesViewController делать с представлением, из которого вы возвращаетесь drawView ? Кроме того, что такое родительский класс Trophy ?

5. Привет, Филипп, я обновил первый пост

Ответ №1:

Сохраняйте строгую ссылку на trofeoPrimaVisita как свойство вызывающего объекта вместо того, чтобы иметь is как локальную переменную.

Я предполагаю, что вы используете ARC, и объект ( Trophy ), который реализует fb: , был выпущен к моменту нажатия кнопки.

Комментарии:

1. Я думал об этом, но тогда мне нужно сгенерировать более одного объекта Trophy в WATrophiesViewController, поэтому я не могу этого сделать.

2. Я не уверен, что вы подразумеваете под «должен генерировать», но вам нужно, чтобы на объект была строгая ссылка, если вы хотите избежать сбоя. Если вам нужно много из них, используйте массив, набор или словарь … все, что имеет смысл.

3. Я использую for для создания экземпляра и создания X трофейных представлений, поэтому, если я объявлю сильное свойство, оно будет заполнено последним объектом.

4. Затем сделайте свойство strong массивом и добавьте к Trophy нему объекты. Другим вариантом было бы Trophy полностью избавиться и поместить обработчики кнопок и логику создания представления в контроллер, который в конечном итоге отображает представления.

5. спасибо, я решил с помощью NSMutableArray с сильной ссылкой, куда я добавил все объекты трофеев.

Ответ №2:

просто удалите двоеточие u, помещенное после имени метода в селекторе. например, заменить @selector(fb:) на @selector(fb) . Я надеюсь, что это поможет 🙂