I need to rename a ObjC Class Implementation File into *.mm, because I'm using a
C++ Framework (Box2D). After renaming the file and setting the Filetype to "sourcecode.cpp.objcpp" my following declaration of private methods produces some errors like:
error: expected identifier before 'private'
The declaration of methods:
#interface GameplayLayer(private)
- (void)spawnTick:(ccTime)delta;
- (void)pushSpawnTick;
#end
How can I use declarations of private methods in ObjC++?
It is probably because private is a keyword in C++. You can either change it to something else like hidden or leave the category name empty (this is called a 'class continuation', you can read more about it by searching in this article.)
this is the way I declare my private methods in Obj-C
basically is just creating a category with no name in the .m
hope this helps
//this is A.h
#interface A
- (void) publicMethod1;
#end
//this is A.m
#interface A ()
- (void) privateMethod1;
#end
#implementation A
- (void) publicMethod1
{
//foo
}
- (void) privateMethod1
{
//foo
}
#end
Related
I am getting an issue when calling a method of return type -(void) in same class
Issue is:Instance method - someMethodName not found (return type defaults to 'id')
Declare someMethodName in your .h file.
The problem is that Xcode can't find a declaration for the method. In most recent version of Xcode you don't need to provide a declaration for a method if the implementation is in the same .m that you are calling it from. e.g.:
//ExampleClass.m
#implementation ExampleClass
-(void)aMethod {
[self anotherMethod]; //Xcode can see anotherMethod so doesn't need a declaration.
}
-(void)anotherMethod {
//...
}
#end
However in earlier version of Xcode you would need to provide a declaration. You can do this in the #interface in .h file:
//example.h
#interface ExampleClass : NSObject
-(void)anotherMethod;
#end
The problem with putting the declaration in the .h is that all other class can see the method, which may cause problems. To get around this you can declare a class continuation within the .m:
//ExampleClass.m
#interface ExampleClass ()
-(void)anotherMethod;
#end
#implementation ExampleClass
//...
#end
DataController.h
#class Play;
#interface DataController : NSObject
- (unsigned)countOfList;
- (Play *)objectInListAtIndex:(unsigned)theIndex;
#end
DataController.m
#import "DataController.h"
#import "Play.h"
#interface DataController ()
#property (nonatomic, copy, readwrite) NSMutableArray *list;
- (void)createDemoData;
#end
#implementation DataController
#synthesize list;
- (id)init {
if (self = [super init]) {
[self createDemoData];
}
return self;
}
Why do you think that #interface is defined twice? And also whats the meaning of ()? Shouldn't there be a class name maybe the super class between the parentheses?
In general, the syntax #interface ClassName (CategoryName) is for declaring a category. Categories are a way to add methods to a class. You can do this even with classes for which you don't have the source code. See more here.
#interface ClassName () (with nothing in the parentheses) is essentially a special case of a category and is called a class extension. The primary difference between a class extension and a category is that methods declared in a class extension must be defined/implemented in the main #implementation block for the class, or you'll get a compiler warning. Methods in a regular category can be defined in an external #implementation block.
The most common use for class extensions (as in this case) is for declaring private methods. Objective-C doesn't have support for true private methods, so an easy way to accomplish the same basic end result is to declare private methods in a class extension at the top of the .m file. Since these methods aren't defined in the .h file, other classes won't see them, and you'll get a compiler warning if you try to use them outside the class they belong to.
You can also redeclare a readonly #property as readwrite in a class extension. That way, code external to the class implementation can only read a property's value, but inside the class's implementation, you can write to it too. This is the only case where it's allowable to redeclare an #property.
(Note that class extensions were a new feature in Objective-C 2.0 and aren't available on Mac OS X 10.4 and earlier.)
I'm arranging my methods into groups using #pragma mark in implementation. But sometimes, the method implementation code appears below the code that calls this method, and I'm getting "Instance method not found" warnings. It happens when I'm using private methods. How to fix that?
Simplest method is to use a anonymous category. Add something like this to the top of your .m file, before your #implementation:
#interface MyClass()
- (void)myPrivateMethod;
#end
In your Class.m implementation file, you can add an interface section at the beginning and declare private functions in there:
#interface YourClassName (private)
-(void)aPrivateMethod:(NSString*)aParameter;
...
#end
#implementation YourClassName
...
#end
In this case, you would use a class extension inside of your implementation file to define these methods. In this manner, your 'public' API is still defined in your header file, and your implementation file contains the definition of your pseudo-private methods.
YourClass.m
#interface MyClass()
- (void)myPrivateMethod;
#end
#implementation MyClass
- (void)myPublicMethod
{
// This will not throw an error or warning
[self myPrivateMethod];
}
- (void)myPrivateMethod
{
// Do something
}
#end
I am writing my first lines in objective-c for an iPhone app.
This is the code:
/* ViewController.h */
#protocol ImageFlowScrollViewDelegate;
#interface ViewController : UIViewController<ImageFlowScrollViewDelegate> {
NSMutableArray *characters;
UILabel *actorName;
}
/* ViewController.m */
#import "ImageFlowScrollView.h"
#implementation IMDBViewController
/* methods here */
/* ImageFlowScrollView.h */
#protocol ImageFlowScrollViewDelegate;
#interface ImageFlowScrollView : UIScrollView<UIScrollViewDelegate> {
NSMutableArray *buttonsArray;
id<ImageFlowScrollViewDelegate> imageFlowScrollViewDelegate;
}
#property(nonatomic, assign)id<ImageFlowScrollViewDelegate> imageFlowScrollViewDelegate;
- (id)initWithFrame:(CGRect)frame imageArray:(NSArray *) anArray;
- (void)focusImageAtIndex:(NSInteger) index;
#end
#protocol ImageFlowScrollViewDelegate<NSObject>
#optional
- (void)imageFlow:(ImageFlowScrollView *)sender didFocusObjectAtIndex: (NSInteger) index;
- (void)imageFlow:(ImageFlowScrollView *)sender didSelectObjectAtIndex: (NSInteger) index;
#end
Doing this, I get a
warning: no definition of protocol
'ImageFlowScrollViewDelegate' is found
I can fix it using:
#import "ImageFlowScrollView.h"
#interface IMDBViewController : UIViewController<ImageFlowScrollViewDelegate> {
NSMutableArray *characters;
UILabel *actorName;
}
but I would like to know why the forward declaration approach is giving me a warning.
The forward declaration defines the symbol so the parser can accept it. But when you try to use the protocol (or class) - as you do by conforming to the protocol - the compiler needs it's definition to know the layout and size of the resulting object.
In addition, you can forward a class or protocol when you are only using it in the class (in an ivar for example). The compiler then only needs to know the existence of the symbol. But when making use of the class (in the implementation file), the methods need to be declared before use hence the need to include the declaration.
For example :
/* AViewController.h */
#class AnotherClass;
#interface AViewController : UIViewController {
AnotherClass* aClass; //only need the declaration of the name
}
#end
/* AViewController.m */
#import "AnotherClass.h"
#implementation AViewController
- (void) useAnotherClass {
[AnotherClass aMessage]; //aMessage needs to be declared somewhere, hence the import
}
#end
In addition, you already know that you must provide actual implementations in order to link your program.
i'm getting this two messages:
warning: 'MainView' may not respond to '-switchToNoGridView'
Messages without a matching method signature will be assumed to return 'id' and accept '...' as arguments
1st here:
//GridView.m
#import "GridView.h"
#import "MainView.h"
#implementation GridView
-(IBAction)switchToNoGridView {
[mainView switchToNoGridView];
}
#end
2nd here:
warning: 'MainView' may not respond to '-goBack'
Messages without a matching method signature will be assumed to return 'id' and accept '...' as arguments
in this:
//NoGridView.m
#import "NoGridView.h"
#import "MainView.h"
#implementation NoGridView
-(IBAction)goBack {
[mainView goBack];
}
#end
how to avoid these warnings?
Have you declared switchToNoGridView and goBack in the class interface for MainView?
This warning means that the method signatures could not be found in the class of the instance that you are calling the method on; since message dispatch in Objective-C is done at runtime this is allowed, however a warning is shown.
I'm not quite sure from your code, but I think you're encountering one of two errors. Either:
You haven't declared the methods switchToNoGridView or goBack in the MainView class declaration. For Xcode to know that an object responds to a method, you have to include its definition in the class header file, like this:
#interface MainView : ParentObject {
// instance variables
}
// properties
- (void)switchToNoGridView;
- (void)goBack;
#end
This assumes you actually want to declare them as (void), of course - they can have return values, but since you don't do anything with the result of the call in your code, I'm assuming they're void. Or:
You meant to call MainView the class, not mainView the object. Since we can't see your property or instance variable definitions for GridView.h, nor can we see the current method declarations in MainView.h, it's possible that you have a static method +(void)switchToNoGridView and +(void)goBack declared on MainView, but you're calling it on an instance mainView of MainView. For example:
#interface AClass : NSObject { }
+ (void)doSomething;
#end
#implementation AClass
+ (void)doSomething {
NSLog(#"Doing something");
}
#end
#import "AClass.h"
#interface AnotherClass : NSObject {
AClass *aClass;
}
#property(nonatomic,retain) AClass *aClass;
- (void)doSomethingElse;
#end
#implementation AnotherClass
- (void)doSomethingElse {
[aClass doSomething]; // This will break at runtime
[AClass doSomething]; // but this won't
}
#end
Basically, it's possible you've confused class methods with object methods. Either way, you should check your MainView header file for the appropriate method definitions.