How to use self class method on iPhone? (conceptual question) - iphone

I write an instance method in ClassName.m:
-(void)methodName:(paraType)parameter
{...}
And call it using [self methodName:parameter]; A warning will pop up, but the code still runs successfully.
Is this because I haven't created an instance of the class? Why the method still runs normally? And what is the correct way to call self method to prevent the warning?

Well the first step in receiving help with a warning would be to post the warning :)
I am assuming it is something about an unrecognized message? If so it's because although the compiler sees the call to "methodName" it does not know if that is valid for the object or not.
I would guess your code looks like;
-(void) someFunc
{
...
[self methodName:parameter];
...
}
-(void)methodName:(paraType)parameter
{
...
}
You can either;
a) Place the 'methodName' function earlier in the file so the compiler has seen it before it's used in calls.
b) declare it in the class interface. E.g.
// Foo.h
#interface Foo {
...
}
-(void) methodName:(paraType)parameter;
#end

What is the warning that you get?
Do you have a definition of the method in your header file?
The syntax you use is the propper way of calling method on self.

The method will work because Objective-C methods are resolved at run-time. I expect the warning you get is something like "Object Foo may not respond to -methodName:" and then it tells you that it's defaulting the return type to id. That's because the compiler hasn't seen a declaration or definition of -methodName: by the time it compiles the code where you call it. To remove the warning, declare the method in either the class's interface or a category on the class.

If you are getting a warning it might be because the method signature isn't in an interface.
#interface foo ....
-(void)method;
Once the implementation is written the warning should go away since it's not the first time the compiler has seen the method. It will work without doing this, but the warning message is annoying.

Related

Why does xcode sometimes find instance methods not declared in header files?

Of course it is best practice to declare all methods in the header file, so I appreciate when xcode warns me than an instance method may not be found. However, there are cases when I have not declared a method in the header, and I do not get a warning. These are definitely not any delegate methods, so what other cases would cause this behavior?
Probably the method has already been defined in the implementation by the time it is used. i.e. if the method being used is above the place it's used in the implementation file then the compiler knows the method signature so all is OK.
if your method is not declared in the header file (or a class extension), but comes before another method which is referencing it then you won't get an error.
If you call your method under your method body definition it works, like:
-(void)foo { bla }
[self foo];
If you too the other way around it crashes (if the method it not in your header file):
[self foo];
-(void)foo { bla }

how to fault find if a delegate call is not being picked up in objective-c

Just implementing my first delegate in objective-C. I thought I had everything in place however the call from my AddController back to ListController isn't being picked up in the ListController.
Given that I'm not getting an exception, and that I can see that the code does get to the point in the AddController where it calls the delegate, are there any fault finding tips?
So for example:
given the "delegate" call (see below) did not throw an exception can I assume that my delegate declarations in the same file are OK?
"[delegate newItemController:self didFinishWithSave:YES];"
given the parent controller so to speak does have the delegate specified in the *.h definition (see below), then this does implied I've correctly implemented the method in the *.m file, noting I get no build errors?
#interface RootViewController : UITableViewController {
is there a known way for delegate calls to go missing without an exception if certain items don't like up (i.e. if there is what should I check for)
thanks
Most common error I've seen for a delegate method not being called is a nil delegate property. In other words, forgetting to specify who the delegate is?
As for debugging tips, anytime I've seen a problem where a delegate is not being called is to set breakpoints throughout the code and step through the code. Then you can see where things are going and what is or isn't being called.
Also, you mention exceptions a lot. Objective C prefers not to use exceptions as they are a relatively expensive call in the language (unlike say Java). Objective C can and does use exceptions but they are rare. You might want to "beaf up" your understanding of error handling in objective c.
Have you set your delegate variable like this in your AddController:
self.delegate = <instance of ListViewController>
If it has not been set, then the delegate would be nil and the method call to the nil would result in nothing. Otherwise, delegate calls wouldn't really go missing like that.
I didn't understand your second point though.

Unnecessary warnings in the code

I am not able to find out why am I getting unnecessary warnings like:
"Method 'someMethod' not found"? Though at run time it is executing this method and I am getting the desired results. FYI... The called method resides in separate class which i have already imported in my class.
Usually one of two reasons:
1) You haven't casted the object that you're calling that method on correctly.
[(UITableView*)myTableView setDelegate:self];
2) The method that you're calling may not be in your custom Class' (public) #interface
#interface MyCustomClass : NSObject {
}
- (void)doSomethingReallyImportant;
#end
If you are trying to do something to an object, did you cast your object to the object's class?
If you are trying to access a method in your implementation of a class, do you have that method declared in your .h?
Then you have probably not put that method in the class' #interface. You should if it is a public method.
Being able to compile without warnings is a good thing.

Objective-C: call a method you just created

Simple question, as I am coming from another programming language. In Objective-C, lets say in a controller class I want to separate certain code into its own method, how do I call that method let's say, from viewLoad. As an example, let's say I create a method:
(void)checkIfInputCorrect
{
NSLog(#"text");
}
Now, i wanted to have in a delegate method, call this method. I tried [self checkIfInputCorrect] and get a warning saying Controller may not respond to -CheckIf...
I thought something like checkIfInputCorrect() would work that gives an error as well.
Basically how do you call a method?
Add this to your .h file
- (void)checkIfInputCorrect;
Call it with:
[self checkIfInputCorrect];
You need to list the method in the interface (ideal) or list the method implementation before the calling method (less ideal) so that the compiler can know that the class responds to the selector before it compiles the calling line.
To paraphrase Martin,
In your .m file, make sure your method -checkIfInputCorrect is placed so that it's physically above the method that has the line: [self checkIfInputCorrect];

Getting Xcode to drop "No XXX method found" warning when delegating

This could be me doing the design pattern wrong.
I'm implementing asynchronous delegation in an application that uses NSURLConnection. An object wraps the NSURLConnection and handles its delegated messages; that works fine. Now I'm defining my own delegates in the object that uses it (NSURLConnection messages ConnectionWrapper, ConnectionWrapper messages NeedsToUseConnection, you get the idea), and that works as well, however, Xcode emits this warning:
No '-request:finishedWithResult' method found
This is, presumably, because I'm declaring the delegate I'm calling like this:
id<NSObject> delegate;
...and Xcode is checking what NSObject declares in the Foundation framework. My custom delegate message is not there. I am properly insulating the call:
if([delegate respondsToSelector:#selector(request:finishedWithResult:)])
[delegate request:self finishedWithResult:ret];
Aside from turning the warning off -- I like to work with as many warnings on as possible -- is there a way to communicate (either syntactically or via a compiler directive) that I am aware this message is undeclared? Should I, instead, be using an interface design pattern for this รก la Java? Using id<WillReceiveRequestMessages> or something?
Open to suggestion.
A better way of doing it would be to create your own delegate protocol:
#protocol MyControlDelegate <NSObject>
#optional
- (void)request:(MyControl *)request didFinishWithResult:(id)result;
#end
Then, you would declare your delegate like this:
id <MyControlDelegate> delegate;
The compiler will no longer complain when you write this:
if ([delegate respondsToSelector:#selector(request:didFinishWithResult:)])
[delegate request:self didFinishWithResult:result];
The <NSObject> syntax is important in the protocol definition because it tells the compiler to incorporate the NSObject protocol. This is how your protocol gets methods like respondsToSelector:. If you left that out, the compiler would start complaining about respondsToSelector: instead.
This is, presumably, because I'm declaring the delegate I'm calling
like this: ...and Xcode is checking what NSObject declares in the
Foundation framework.
That is incorrect. If that were the case then you would get a warning about the object "may not respond to" the method, or something like that. This is a completely separate problem.
This warning is due to the fact that the compiler must know the signature of a selector in order to call it. This is because, behind the scenes, the compiler translates a method call to either objc_msgSend or objc_msgSend_stret depending on whether the method returns a struct type or not. If it doesn't know the return type, it will guess that it is not a struct, and use the first function. However, this could be wrong.
The solution is to have the method declared anywhere at all. It doesn't even have to be declared in the right class. You can declare it in some dummy protocol that is never used. So long as it is declared somewhere, the compiler will know and will be able to correctly compile it.