Reputation: 23
I'm following and online course and got stock because even by following the step (or maybe I missed some ? ) i get and error. I made several search on google and here but since i'm new to IOS development, even with answer from others, i can relate to my issue..
here is the error:
2015-06-12 23:03:17.477 Pirate Game[6511:1193126] -[RBTile setWeapon:]: unrecognized selector sent to instance 0x78830dc0
2015-06-12 23:03:17.481 Pirate Game[6511:1193126] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[RBTile setWeapon:]: unrecognized selector sent to instance 0x78830dc0'
*** First throw call stack:
(
0 CoreFoundation 0x00874746 __exceptionPreprocess + 182
1 libobjc.A.dylib 0x004fda97 objc_exception_throw + 44
2 CoreFoundation 0x0087c705 -[NSObject(NSObject) doesNotRecognizeSelector:] + 277
3 CoreFoundation 0x007c3287 ___forwarding___ + 1047
4 CoreFoundation 0x007c2e4e _CF_forwarding_prep_0 + 14
5 Pirate Game 0x00014a94 -[RBFactory tiles] + 388
6 Pirate Game 0x00011c6f -[ViewController viewDidLoad] + 143
7 UIKit 0x00d97da4 -[UIViewController loadViewIfRequired] + 771
8 UIKit 0x00d98095 -[UIViewController view] + 35
9 UIKit 0x00c89e85 -[UIWindow addRootViewControllerViewIfPossible] + 66
10 UIKit 0x00c8a34c -[UIWindow _setHidden:forced:] + 287
11 UIKit 0x00c8a648 -[UIWindow _orderFrontWithoutMakingKey] + 49
12 UIKit 0x00c989b6 -[UIWindow makeKeyAndVisible] + 80
13 UIKit 0x00c2ded8 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 3217
14 UIKit 0x00c31422 -[UIApplication _runWithMainScene:transitionContext:completion:] + 1639
15 UIKit 0x00c4a93e __84-[UIApplication _handleApplicationActivationWithScene:transitionContext:completion:]_block_invoke + 59
16 UIKit 0x00c3004a -[UIApplication workspaceDidEndTransaction:] + 155
17 FrontBoardServices 0x031d6c9e __37-[FBSWorkspace clientEndTransaction:]_block_invoke_2 + 71
18 FrontBoardServices 0x031d672f __40-[FBSWorkspace _performDelegateCallOut:]_block_invoke + 54
19 FrontBoardServices 0x031e8d7c __31-[FBSSerialQueue performAsync:]_block_invoke_2 + 30
20 CoreFoundation 0x00796050 __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 16
21 CoreFoundation 0x0078b963 __CFRunLoopDoBlocks + 195
22 CoreFoundation 0x0078b7bb __CFRunLoopRun + 2715
23 CoreFoundation 0x0078aa5b CFRunLoopRunSpecific + 443
24 CoreFoundation 0x0078a88b CFRunLoopRunInMode + 123
25 UIKit 0x00c2fa02 -[UIApplication _run] + 571
26 UIKit 0x00c33106 UIApplicationMain + 1526
27 Pirate Game 0x000148da main + 138
28 libdyld.dylib 0x02c00ac9 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
So what i could understand from my search, is that i'm trying to send something that is not the same type. I have the same problem with all 3 custom class.
//
// RBFactory.m
// Pirate Game
//
// Created by Richard Berube on 2015-06-06.
// Copyright (c) 2015 Richard Berube. All rights reserved.
//
#import "RBFactory.h"
#import "RBTile.h"
@implementation RBFactory
-(NSArray *)tiles{
RBTile *tile1 = [[RBTile alloc] init];
tile1.story = @"Captain, we need a fearless leader such as you to undertake a voyage. You must stop the evil pirate Boss before he steals any more plunder. Would you like a blunted sword to get started?";
tile1.backgroundImage = [UIImage imageNamed:@"PirateStart.png"];
CCWeapon *bluntedSword = [[CCWeapon alloc]init];
bluntedSword.name = @"Blunted sword";
bluntedSword.damage = 12;
NSLog(@"%@", bluntedSword);
tile1.weapon = bluntedSword;
tile1.actionButtonName =@"Take the sword";
I tested with breakpoint and the crash occure
tile1.weapon = bluntedSword;
NSLog return:
2015-06-12 23:03:14.602 Pirate Game[6511:1193126] <CCWeapon: 0x786a6f50>
here is the tile class
//
// RBTile.h
// Pirate Game
//
// Created by Richard Berube on 2015-06-06.
// Copyright (c) 2015 Richard Berube. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "CCWeapon.h"
#import "CCArmor.h"
@interface RBTile : NSObject
@property (nonatomic, strong) NSString *story;
@property (strong, nonatomic) UIImage *backgroundImage;
@property (nonatomic, strong) NSString *actionButtonName;
@property (strong, nonatomic) CCWeapon *weapon;
@property (strong, nonatomic) CCArmor *armor;
@property (nonatomic) int healthEffect;
@end
The .m file is empty
//
// RBTile.m
// Pirate Game
//
// Created by Richard Berube on 2015-06-06.
// Copyright (c) 2015 Richard Berube. All rights reserved.
//
#import "RBTile.h"
@implementation RBTile
@end
And the last one is the custom class, one of them actualy, because all 3 are causing the same issue..
//
// CCWeapon.h
// Pirate Game
//
// Created by Richard Berube on 2015-06-10.
// Copyright (c) 2015 Richard Berube. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface CCWeapon : NSObject
@property (strong,nonatomic) NSString *name;
@property (nonatomic) int damage;
@end
A little help would be really apreciated! i'm now stock since 2 days.. i could start over all the video (online course) but that won't teach me how to debug ..
Maybe the last usefull info could be that i used Xcode 6.3.1
THanks !
update 1 : The final project is this one https://github.com/codecoalition/Pirate-Adventure-Assignment/tree/master/Pirate%20Adventure
my RBtile is the CCtile in the github project
update 2: here is my viewcontroler
//
// ViewController.m
// Pirate Game
//
// Created by Richard Berube on 2015-06-06.
// Copyright (c) 2015 Richard Berube. All rights reserved.
//
#import "ViewController.h"
#import "RBFactory.h"
#import "RBTile.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
RBFactory *factory = [[RBFactory alloc]init];
self.tiles = [factory tiles];
self.character = [factory character];
self.currentPoint = CGPointMake(0, 0);
[self updateTile];
[self updateButtons];
[self updateCharacterStatsForArmor:nil withWeapons:nil withHealthEffect:0];
}
-(void)updateTile{
RBTile *tileModel = [[self.tiles objectAtIndex:self.currentPoint.x] objectAtIndex:self.currentPoint.y];
self.storyLabel.text = tileModel.story;
self.backgroundImageView.image = tileModel.backgroundImage;
self.healthLabel.text = [NSString stringWithFormat:@"%i", self.character.health];
self.damageLabel.text = [NSString stringWithFormat:@"%i", self.character.damage];
self.armorLabel.text = self.character.armor.name;
self.weaponLabel.text = self.character.weapon.name;
[self.actionButton setTitle:tileModel.actionButtonName forState:UIControlStateNormal];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)actionButtonPressed:(UIButton *)sender {
RBTile *tile = [[self.tiles objectAtIndex:self.currentPoint.x] objectAtIndex:self.currentPoint.y];
[self updateCharacterStatsForArmor:tile.armor withWeapons:tile.weapon withHealthEffect:tile.healthEffect];
[self updateTile];
}
- (IBAction)northButtonPressed:(UIButton *)sender {
self.currentPoint = CGPointMake(self.currentPoint.x, self.currentPoint.y +1);
[self updateButtons];
[self updateTile];
}
- (IBAction)southButtonPressed:(UIButton *)sender {
self.currentPoint = CGPointMake(self.currentPoint.x, self.currentPoint.y -1);
[self updateButtons];
[self updateTile];
}
- (IBAction)eastButtonPressed:(UIButton *)sender {
self.currentPoint = CGPointMake(self.currentPoint.x + 1, self.currentPoint.y);
[self updateButtons];
[self updateTile];
}
- (IBAction)westButtonPressed:(UIButton *)sender {
self.currentPoint = CGPointMake(self.currentPoint.x - 1, self.currentPoint.y);
[self updateButtons];
[self updateTile];
}
- (IBAction)restartButtonPressed:(UIButton *)sender {
}
-(void)updateButtons{
self.westButton.hidden = [self tilesExistAtPoint:CGPointMake(self.currentPoint.x -1, self.currentPoint.y)];
self.eastButton.hidden = [self tilesExistAtPoint:CGPointMake(self.currentPoint.x+1, self.currentPoint.y)];
self.northButton.hidden = [self tilesExistAtPoint:CGPointMake(self.currentPoint.x, self.currentPoint.y+1)];
self.southButton.hidden = [self tilesExistAtPoint:CGPointMake(self.currentPoint.x, self.currentPoint.y-1)];
}
-(BOOL)tilesExistAtPoint:(CGPoint)point{
if (point.y >= 0 && point.x >=0 && point.x < [self.tiles count] && point.y < [[self.tiles objectAtIndex:point.x] count]) {
return NO;
}
else{
return YES;
}
}
-(void)updateCharacterStatsForArmor:(CCArmor *)armor withWeapons:(CCWeapon *)weapon withHealthEffect:(int)healtEffect{
if (armor != nil ) {
self.character.health = self.character.health - self.character.armor.health +armor.health;
self.character.armor = armor;
}
else if (weapon != nil){
self.character.damage = self.character.damage - self.character.weapon.damage + weapon.damage;
self.character.weapon = weapon;
}
else if (healtEffect != 0){
self.character.health = self.character.health + healtEffect;
}
else {
self.character.health = self.character.health + self.character.armor.health;
self.character.damage = self.character.damage + self.character.weapon.damage;
}
}
@end
Another update:
I was able to find with the breakpoint that some of my property are not showing up..
When in fact it should be like that:
So now i know that when i try to pass tile1.weapon = bluntedSword;
it is not working because tile1.weapon
do not exist. But if you look in my RBTile.h
all my property are there..
Upvotes: 2
Views: 232
Reputation: 1499
I am following the same course, and my code is the same as yours, and it works. The Tile.m
files is empty.
In recent Xcode versions, synthesize
statements are not always necessary. Some rare cases, I think, still need them.
I think the reason you don't see the other properties in the debug window is because the code that creates them hasn't run yet.
Try commenting out the lines that related to bluntedSword
and see if the other properties are set successfully, or if they also cause the app to crash.
Another thing to try, and I understand how silly it sounds, is to re-type the lines (not copy and paste) and related lines that are causing the problems. Sometimes this works, so it's worth trying.
Good luck!
Upvotes: 1
Reputation: 7414
The root of the issue is this
[RBTile setWeapon:]: unrecognized selector sent to instance 0x78830dc0
That is telling you that your RBTile.weapon
property on the RBTile
class does not have a setter. Please update your post with the .m
file showing how you are creating the weapon
property on the RBTile
. Odds are you are declaring a getter and potentially forgetting the setter.
Your .m file is empty, which is causing the issue. The header file just defines a contract between an object using your class, and the implementation of the class in the .m file. You can think of it as a bridge of sorts between something using the class, and the actual implementation of the class.
At runtime, the game can't find an implementation of the property to work with, thus the reason why unrecognized selector
is being thrown.
Upvotes: 0