My first shot at creating a method with multiple parameters. Still trying to wrap my head around how Objective C does things. Been banging my head for a couple days on this now. Finally ready to ask for help. Searched and tried many posts here on stack overflow. Below is various code chunks I'm working with ... this is a cocos2d v3 project FYI.
// MainPlayScene.h
#import <Foundation/Foundation.h>
#import "cocos2d.h"
#include <sys/sysctl.h>
#interface MainPlayScene : CCScene <CCPhysicsCollisionDelegate>
+ (MainPlayScene *)scene;
- (id)init;
- (void)evaluateTileAttack:(CCNode*)tileTouchedCCNode : (CCNode*)tileTouchedCCNode2;
#end
// MainPlayScene.m
#import "cocos2d.h"
#import "MainPlayScene.h"
#implementation MainPlayScene
{
CCNode *tileTouchedCCNode;
CCNode *tileTouchedCCNode2;
}
+ (instancetype)scene
{
return [[self alloc] init];
}
- (id)init
{
return self;
}
- (void)evaluateTileAttack: (CCNode*)ccnode1 : (CCNode*)ccnode2
{
NSLog(#"ccnode1: %#", ccnode1.physicsBody.collisionType);
NSLog(#"ccnode2: %#", ccnode2.physicsBody.collisionType);
}
- (void)actionMenuAttackHandler: (id)sender
{
[self evaluateTileAttack: tileTouchedCCNode, tileTouchedCCNode2];
^^^^^^^^^^^^^^^^^^^^^
error at this line
}
#end
ERROR: No visible #interface for 'MainPlayScene' declares the selector 'evaluateTileAttack:'
Not sure why I am getting this error because I think I am declaring in MainPlayScene.h properly ...
The method declaration, though technically valid I think, is at least unusual for ObjC. Best seen when you wrap and align (as is customary for long method calls/declarations) on the colon:
- (void)evaluateTileAttack:(CCNode*)tileTouchedCCNode
:(CCNode*)tileTouchedCCNode2;
Normally a method has a name for all parameters:
- (void)evaluateTileAttack:(CCNode*)tileTouchedCCNode
otherNode:(CCNode*)tileTouchedCCNode2;
The call is definitely invalid, ObjC methods do not take a comma-separated list of parameters (unless specifically declared to do so, which is rare). So this is illegal:
[self evaluateTileAttack: tileTouchedCCNode, tileTouchedCCNode2];
Instead it should be (not sure about this unnamed format though):
[self evaluateTileAttack:tileTouchedCCNode
:tileTouchedCCNode2];
This definitely works and is the expected/recommended approach:
[self evaluateTileAttack:tileTouchedCCNode
otherNode:tileTouchedCCNode2];
Related
I have a problem with my code
#import <Foundation/Foundation.h>
#protocol ServiceDelegate <NSObject>
-(void)serviceFinished:(id)service withError:(BOOL)error {
if (!error)
[searchResults removeAllObjects];
for (NSDictionary *movie in [service results]) {
[searchResults addObject:[movie valueForKey:#"title"]];
}
[[self tableView] reloadData];
}
#end
it keeps telling me to put a ; instead of { in this line
-(void)serviceFinished:(id)service withError:(BOOL)error {
however If i replace the { then the code breaks and doesn't work. and tells me that the second line of code
if (!error) {
the if has the error "Expected identifier or '('
any ideas on how to make it work?
Your interface code:
#import <UIKit/UIKit.h>
#interface FilmTableViewController : UITableViewController
#end
#interface initWithStyle : NSString
- (void)UITableViewStyle:(NSString*);
#end
is wrong. It should be:
#import <UIKit/UIKit.h>
#interface FilmTableViewController : UITableViewController
- (id)initWithStyle:(UITableViewStyle)style;
#end
#interface should always be followed by the class name -and, if applicable, : and the superclass name, and adopted protocols inside angled brackets (and separated by commas)-. The interface declaration for methods is the same as the function header in the implementation (definition), with a semicolon (;) at the end (same rule as for C functions, but must be withing the #interface... / #end pair.)
Addendum: You mentioned that iti is the .m file that seems to be causing the error; However, your method definition of - (id)initWithStyle:(UITableViewStyle)style looks OK... So, which line does Xcode point to? What is the actual error message?
Addendum 2: You are missing a closing } between the method body of -tableView:cellForRowAtIndexPath: and initWithStyle: (right after return cell;), that is why the compiler isn't interpreting the method definition as proper code. Your code is broken.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have a problem that I hope you can help me with. I have an app with several storyboard views, each with a separate viewcontroller. I want to be able to use my own class in all views in the storyboard. This will make the code in each viewcontroller much cleaner and the whole app easier to debug etc. The class will contain variables and methods.
The overall aim for me is to collect data from the user via buttons and then store these in a database. It will be possible to view and amend data, as well as generating statistics.
As most variables and methods will be used in different views and at different times, I would like to separate all these in separate files.
I can also tell you that this is not a lazy short-cut attempt from me, I have surfed the internet for many, many hours reading hundreds of posts etc and I am still nowhere nearer a solution.
Any input is very much appreciated!
Thank you for taking your time to read this...
SomeClass.h has the following code:
#import <Foundation/Foundation.h>
#interface SomeClass : NSObject
{
NSString *dataOne;
NSString *dataTwo;
NSString *dataThree;
}
- (void) SetDataOne: (NSString*) dataOneReceived;
- (void) SetDataTwo: (NSString*) dataTwoReceived;
- (void) SetDataThree: (NSString*) dataThreeReceived;
- (void) saveSomeData;
#end
SomeClass.m has the following code:
#import "SomeClass.h"
#implementation SomeClass
- (void) SetDataOne: (NSString*) dataOneReceived {
dataOne = dataOneReceived;
}
- (void) SetDataTwo: (NSString*) dataTwoReceived {
dataTwo = dataTwoReceived;
}
- (void) SetDataThree: (NSString*) dataThreeReceived {
dataThree = dataThreeReceived;
}
- (void) saveSomeData {
// Here I do stuff with dataOne etc…
}
#end
SomeView.h has the following code:
#import <UIKit/UIKit.h>
#import "HeadViewController.h"
#import "SomeClass.h"
#interface SomeView : UIViewController
// contains stuff not needed to show here
- (IBAction)Done:(id)sender;
#end
SomeView.m has the following code:
#import "SomeView.h"
#import "SomeClass.h"
#interface SomeView ()
#end
#implementation SomeView
- (void)viewDidLoad
{
[super viewDidLoad];
SomeClass *someClassObject = [[SomeClass alloc] init];
// Do any additional setup after loading the view.
}
// Other standard methods omitted
- (IBAction)Done:(id)sender {
[someClassObject SetDataOne: #”whatever text”];
[someClassObject SetDataTwo: #”whatever text”];
[someClassObject SetDataThree: #”whatever text”];
[someClassObject SaveSomeData];
Error Msg for all the above: ”Use of Undeclared Identifier ’someClassObject’
}
#end
Comment: You can see the error message I get at the end of the code above. I have no clue what I am doing wrong. I have looked at a lot of examples on how to create and call classes, but cannot seem anything that solves my problem. Also, I see that some of the put the ”SomeClass *someClassObject = [[SomeClass alloc] init];” in the ”main.m file”. If I understand correctly, that file is the first one to load when app starts. If so, then I cannot place it there as I will have to create instances of my class in several different views and other times than when the app starts. That is why I have placed it in the viewDidLoad-method.
A couple of thoughts:
You've made someClassObject a local variable of the viewDidLoad method. Looks like you meant to make it a class instance variable (or, better, a private class property, which will have the instance variable synthesized for you). Thus:
#interface SomeView ()
#property (nonatomic, strong) SomeClass *someClassObject;
#end
#implementation SomeView
- (void)viewDidLoad
{
[super viewDidLoad];
self.someClassObject = [[SomeClass alloc] init];
}
- (IBAction)done:(id)sender {
[self.someClassObject setDataOne: #"whatever text"];
[self.someClassObject setDataTwo: #"whatever text"];
[self.someClassObject setDataThree: #"whatever text"];
[self.someClassObject saveSomeData];
// should resolve the Error Msg for all the above: ”Use of Undeclared Identifier ’someClassObject’
}
BTW, as a matter of convention, your method names should start with a lowercase letter (e.g. setDataOne not SetDataOne, done rather than Done, etc.), as illustrated above.
If you're going to write your own setters, setDataOne, setDataTwo, etc., you might as well remove those three instance variables, remove your three setData___ methods, and replace the three instance variables with class properties (and let the compiler synthesize not only the instance variables, but the setters, too).
someClassObject is set inside viewDidLoad and because it is not stored anywhere inside the view will be deleted at the end of that very same method
You should add your object inside each header file's interface section like this:
SomeView.h
#import <UIKit/UIKit.h>
#import "HeadViewController.h"
#import "SomeClass.h"
#interface SomeView : UIViewController
{
SomeClass *someClassObject;
}
// contains stuff not needed to show here
- (IBAction)Done:(id)sender;
#end
Then when you instantiate someClassObject inside ViewDidLoad it will persist throughout that view.
It works now, the problem was with Xcode.It was solved by restarting Xcode and trying a clean build, thanks for trying!
Parent Class
CardGame.h
#import <Foundation/Foundation.h>
#import "Deck.h"
#interface CardGame : NSObject
- (id) initWithCardCount:(NSUInteger)cardCount usingDeck:(Deck *) deck;
- (Card *) cardAtIndex: (NSUInteger) index;
#end
Child Class
CardMatchingGame.h
#import "CardGame.h"
#interface CardMatchingGame : CardGame
- (void) flipCardAtIndex: (NSUInteger) index;
#end
CardMatchingGame.m
- (void) flipCardAtIndex: (NSUInteger) index {
Card *card = [self cardAtIndex:index]; // The error I get is on this line
self.currentAction = [NSString stringWithFormat:#"You flipped up %#",
card.contents];
The error I get
No visible #interface for 'CardMatchingGame' declares the selector cardAtIndex: (NSUInteger) index;
I have browsed through similar questions but the answer has to do with the child class not finding the correct parent file, this is not the case for me. I'm a novice in inheritance, am I doing this wrong?
You need to import CardGame.h. If you don't import it, the complier complains that it can't find it, since you don't refer to it in your subclass code.
Example: type import "CardGame.h" at the top of CardMatchingGame.h
The problem seems to be in your implementation of cardAtIndex: - you are making some mistake in that code. My guess is that you might be calling initWithCardCount: the wrong way - perhaps as a class method when in fact it is an instance method.
Sorry to keep asking basic questions here but I don't know where else to go. Wrote some code with a slider, textfield and buttons for incrementing the slider to demonstrate key value coding. Everything worked find. The next step was to use 'property' and 'synthesize' in place of the accessor and setter methods;
#import <Foundation/Foundation.h>
#interface KVCController : NSObject {
int fido;
}
#property(readwrite, assign) int fido;
#end
~~~~~
#implementation KVCController
#synthesize fido;
- (id)init{
self = [super init];
if (self) {
// Initialization code here.
[self setValue:[NSNumber numberWithInt:5] forKey:#"fido"];
NSNumber *n = [self valueForKey:#"fido"];
NSLog(#"fido = %#", n);
}
return self;
}
~~~~~~~
#end
I get an incomplete implementation error on #implementation KVCController. If I put the get and set methods for 'fido' in it clears up.
The second error occurs with #synthesize fido;. It says property must be declared in the implementation. Everything is copied correctly out of the book and near as I can tell, it looks just like all the other uses of property and synthesize I have looked at. Anyone have any ideas on what I am missing or doing wrong?
Xcode 4.1 automatically creates a delegate class which I usually ignore if I am not working on delegates. I created my own class for the KVC exercise and just added the property/synthesize declarations to it with appropriate modifications and got the errors. I just put the property/synthesize declarations into the delegate class, moved my IBAction code to the appropriate places, redid the bindings, and erased the class I created and everything worked fine. Do property/synthesize declarations need to be treated like delegate material?
incomplete implementation means you have a -(void)something that may be defined in your header that you are not using in your #implementation. Make sure that you do not have any unused methods listed in your header. if you do, either remove them from the header, or create the method in your implementation.
- (void) dosomething
{
/* blank for now */
}
if you have -(void)dosomething in your implementation, define it in your header.
#import <Foundation/Foundation.h>
#interface KVCController : NSObject {
int fido;
}
#property(readwrite, assign) int fido;
- (void) dosomething;
#end
I am really new to objective C, and I want to make a class that is an NSArray of NSDictionary, and then have a method that grabs a random entries. I know how to make that but I don't understand how to make it in the class. What I mean is I thought that you could put the code that declared (or whatever the correct terminology is) the array just sort of in the middle of the implementation file and then I would write a method under that. The only instance variable I had was the NSArray and that was in the interface file, along with the method prototype (or whatever) and these were the only things that were in the interface file.
I couldn't figure out the problem so I made a test class that was the same but with just an array of simple text strings. I used the same logic here and I'm pretty certain it is totally backward, I don't know in which way though.
This is the interface for the test class:
#import <Foundation/Foundation.h>
#interface TestClass : NSObject {
NSArray *TestArray;
}
#end
And this is the implementation file
#import "TestClass.h"
#implementation TestClass{
NSArray *TestArray;
}
TestArray = [[NSArray alloc] arrayWithObjects:#"stuff",#"things",#"example",#"stuffThings",nil];
#end
You should really read Apple's introduction to Objective-C. It explains the syntax and structure of the language. You must also read the Objective-C memory management guide so that your programs don't leak memory and crash.
Having said that, here's probably what you're trying to create (I took the liberty of changing some of your variable names):
TestClass.h
#import <Foundation/Foundation.h>
#interface TestClass : NSObject {
NSArray* strings_;
}
// Method declarations would go here
// example:
- (NSString*)randomElement;
#end
TestClass.m
#import "TestClass.h"
#import <stdlib.h>
// Notice how the implementation does NOT redefine the instance variables.
#implementation TestClass
// All code must be in a method definition.
// init is analogous to the default constructor in other languages
- (id)init {
if (self = [super init]) {
strings_ = [[NSArray alloc] initWithObjects:#"stuff", #"things", nil];
}
return self;
}
// dealloc is the destructor (note the call to super).
- (void)dealloc {
[strings_ release];
[super dealloc];
}
- (NSString*)randomElement {
NSUInteger index = arc4random() % [strings_ count];
return [strings_ objectAtIndex:index];
}
#end
For random number generation, it's easy to use arc4random() because it doesn't require setting the seed value.