How to make a forward declaration for private method? - iphone

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

Related

Issue when calling a method with return type “void” in same file

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

Proper way to make variable accessible within entire .m file?

As you can tell, I'm new to Objective-C. I currently have a Singleton working, but I'm trying to use it throughout several methods within the same .m file.
Right now I use this to declare/instantiate the Singleton within a method:
GlobalData *globDat=[GlobalData getInstance];
Do I need to declare it within each method, or is there a way to do this at the top of the .m (or .h?) file so I can access it throughout the other methods?
Thanks...
(BTW I've tried placing the line of code shown above under my "#implementation" line, but I get an error: "Initializer element is not a compile-time constant" which I now know is because the line is not within a method.)
You can add a class extension, and store the global data in ivar, like this:
#interface MyClass() {
GlobalData *globDat;
}
#end
#implementation MyClass
-(id) init {
self = [super init];
if (self) {
globDat=[GlobalData getInstance];
}
return self;
}
#end
This will hide the globDat from the interface, and make it available throughout the methods you implement inside your implementation block of MyClass.
when u need a variable / object that is accessible to all methods in an implementation data, u need to declare it on the header file, and then synthesize it on the implementation file (note that u may need to import the GlobalData header)
so
in header (.h):
#class GlobalData;
#properties (nonatomic, strong) GlobalData *globDat;
and then at the implementation file (.m)
#import "blablabla.h"
#import "GlobalData.h"
#implementation blablabla
#synthesize globDat;
-(void)viewDidLoad
{
globDat = [GlobalData getInstance];
}
good luck

Two Interfaces?

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.)

Private Methods in ObjC++

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

warnings in iphone sdk

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.