#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
вызывается на aNSMutableArray
, который, конечно, не реализует метод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)
. Я надеюсь, что это поможет 🙂