Yes all, another newbie question!
I'm doing some maintenance work on an app I inherited and I'm trying to find the code behind this method. In my task.h file I have a optional method, doTask, declared in a protocol, TaskDelegate. In my task.m file I located the method definition for doTask, but it refers back to it's method name so I assumed I'd find another "more complete" method definition in another object. WRONG! I'm obviously missing something very basic here. I haven't been able to find any other references in my code to doTask.
Here's the initial declaration in my header file, task.h
#protocol TaskDelegate<NSObject>
#optional
- (void) doTask;
Here's the method definition in my implementation file, task.m
- (void) doTask
{
if ((self.delegate != nil) && ([self.delegate respondsToSelector:#selector(doTask)]))
{
[self.delegate doTask];
}
}
I assume my method definition is first determining if I have a object delegate already in existence and then seeing if it has a doTask method defined within it; if it does, then it's telling it to execute the doTask method on that delegate. Am I correct?
Well, if so, my question becomes where is the code behind doTask which actually does something? I've really got to be missing something basic here. All help is appreciated! Thanks in advance for your assistance...
As middaparka said, your assumption is spot-on. As for finding the function code for the doTask method, do a Edit -> Find -> Find in Project or command + shift + F and enter 'doTask' (or whatever the function name really is) into the search bar and set it to 'In Project' and it will pull up all instances where the function text shows up, including the function definition.
I assume my method definition is first
determining if I have a object
delegate already in existence and then
seeing if it has a doTask method
defined within it; if it does, then
it's telling it to execute the doTask
method on that delegate. Am I correct?
This is precisely what's happening.
In terms of your "where is the code behind doTask" question - it should be in whatever delegate registers itself with the class in question. (It's a bit confusing in that the same method name is being used but the intent behind the [self.delegate doTask]; line should be clear.)
Related
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 }
I have a data class that starts with a bool value:
- (id)initWithBool:(BOOL)hasSomeValue anotherVariable:(var type)var ...
But this is unreadable when instantiating in XCode, because "hasSomeValue" is not shown when auto-complete appears.
-(id)initWithHasSomeValue:(BOOL)hasSomeValue anotherVariable:(var type)var ...
Is also rather clunky. I've done some searching but can't seem to find Apple's recommended specs on this.
EDIT: A pointer to an example by Apple would help very much. I still haven't managed to find one.
You'd really want something that tells you WHAT the BOOL actually represents
- (id)initWithBool:(BOOL)hasSomeValue ...
- (id)initWithHasSomeValue:(BOOL)hasSomeValue ...
would be comparable to
- (id)initWithString:(NSString*)string ...
if you were initiating a BOOL (which clearly is nonsense), except with [NSNumber numberWithBool:]
Generally speaking, the name of the parameter should describe its semantics, which "bool" doesn't really do. E.g. "initWithName:" is better than "initWithString:".
Even more generally speaking, you have a data class that takes a boolean as it's first parameter? Maybe you need to rethink why it's there at all?
Have you added the custom init method to your header file?
Although it will compile (with a warning) and run fine, the custom init method will only appear in auto complete if it appears in the header file.
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.
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];
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.