invoking a delegate method of a class by code - iphone

is it possible to invoke a delegate method of a class by code?
In my case I want to invoke the searchBar:textDidChange: method in my code!
If yes how would I do that ?

Yes, if you know exactly how to cook the objects for its parameters.
It is just another method and you can call like
[self searchBar:parameter textDidChange:parameter];
IMHO, I would say, in this case, searchBar is in better position to pass the objects, rather than you invoke yourself.

Related

objective-c: multiple class defintions in one .m file, and calling methods

I've defined two classes in an m file, the first subclassing UIView and the second UIViewController. The UIViewController is instantiated at some point, and the vc is who instantiates my first class.
the first class implements the touchesEnded method, to simulate a button. when the touchesEnded method is fired in the first class, is it possible to easily call a method defined in the 2nd class, without going into delegates and such?
I tried playing with selectors with no luck
is it possible to easily call a method defined in the 2nd class
Yes, assuming that you are creating an instance of the second class and calling the method on that instance.
Regardless of whether the two classes are subclasses of the same type, or in the same or different files, you need a reference to an instance of that class to call a method on it, or force it to perform a selector.
The proper OO way to do this is with delegates, but you could theoretically do something like pass a reference to view 2 into view 1 when you create the views. If you create them in IB you could create outlets so they reference each other that way.
In short: Yes, it is possible and easy to do, but I can't give you too much in terms of specific code without a more specific example of your situation

vs [mpk5 weaponAttachments]

I'm able to make the method for the call [self weaponAttachments:mpk5] but I don't like having to call self. I think [mpk5 weaponAttachments] is more natural and is easier to read.
The problem I'm having is I need to pass in the weapon (mpk5) in order to use it, which I can do with the first method but not with the second one. Does this mean that I need to subclass NSDictionary in order to be able to use a statement like [mpk5 weaponAttachments]? If so, how do I get ahold of the caller "mpk5" so that I can use it inside the method?
EDIT
I apologize for not putting this in the first time but my objective is to have [mpk5 weaponAttachments] return an NSDictionary or NSArray. Right now I have NSDictionary *attachments = [self weaponAttachments:mpk5]; which works but it just doesn't seem like the best approach.
So firstly, your two calls are a little mixed up:
[self weaponAttachments:mpk5] calls the weaponAttachments method, passing in the variable mpk5.
But [mpk5 weaponAttachments] is either asking the mpk5 object to return the weaponAttachments property or is asking the mpk5 object to run a method called weaponAttachments (I'm simplifying here - it's always a method, but if you're using properties you probably won't realise this as Objective-C will create them for you).
These are fundamentally different things.
On to the brunt of your question:
I don't like having to call self
...unfortunately, if you're working in an object-oriented language you're going to have to get used to this. Say I have a class called mySimpleClass, and a method inside that class called doSomething. Writing this:
[mySimpleClass doSomething] would be what we call a static method. Whereas calling [self doSomething] from within an instance of mySimpleClass would be an instance method.
If you're unsure of the difference between static and instance methods you should probably step back and take a look at some of the basic guides out there.

Significance of Super?

Can anybody tell me why we need the super in every method for e.g.:
-(void)viewDidLoad
{
[super viewDidLoad];
}
I am confused about the super keyword....
[super ...] calls the implementation of the method in your class's superclass. It is important to use if the inheriting class wants to extend the method implementation (i.e., add something to it but also do what the superclass did) as opposed to replacing the method implementation.
As such, you do not call super in every method you override but only where it is appropriate. If you should, must or must not call super in a specific method should be mentioned in the documentation of that method.
To call the method of the parent class.
This is the rule when you override the method of the superclass, so that you can make sure that code in the superclass get executed and behave correctly.
Note: Sometimes, you call super in the beginning of the method, some other times, in the end of the method

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];

Call back style

I am writing an iPhone application which in numerous places needs to perform non HTTP or FTP networking of a very simple request response type.
I've wrapped all this up into a SimpleQuery class that integrates with the run loop.
SimpleQuery *lookup = [[SimpleQuery alloc] init];
[lookup setDelegate:self];
[lookup doQueryToHost:queryServer port:queryPort query:queryString ];
As you can see the calling object sets itself as a delegate. When the results are complete it then calls a method on the delegate with the results.
[delegate simpleQueryResult:resultString simpleQuery:self];
I am now in a position where I have a user of SimpleQuery that has two types of query so I need to extend SimpleQuery to support this.
I can think of two sensible ways of doing this.
Firstly passing a selector into doQueryString, or a seperate doQueryStringWithSelector.
[lookup doQueryToHost:queryServer port:queryPort query:queryString selector:#SEL ];
Secondly passing a tag into doQueryString so that when the delegate is called it can query the tag, as the simpleQuery is passed, to find out what the results are for.
[lookup doQueryToHost:queryServer port:queryPort query:queryString withTag:tag ];
I'm just wondering which is best from a coding style perspective, the first seems simpler but tagging seems more in keeping with the iPhone SDK and Interface Builder
An option which is used commonly in Apple's code (for example, in UIControl) is to provide both a target object and a selector. This works only if there is a single callback, and is more appropriate than a delegate in that case. (If there are multiple callbacks, then you'll probably have to go with a delegate and the tag approach.)
If you go this route, then you do away with the delegate altogether and instead have a method with a signature like this:
doQueryToHost:(id)queryServer port:(int)queryPort query:(NSString*)queryString target:(id)target action:(SEL)action
Note that "action" is typically preferred over "selector" in methods arguments in this case. The query would simply call the selector on the target when done. This would allow your clients to have multiple selectors, and also multiple target objects; this can help clean up code because you don't need to shove everything into a single delegate object.
If you want to go with your tag route, you should call it "context", which is what Apple uses (for example, in addObserver:forKeyPath:options:context).
There's a third option that's a common pattern in the kits, which is to use #protocols.
For example:
#protocol QueryCompleteHandlerProtocol
- (void)queryType1Complete:(int)intStuff;
- (void)queryType2Complete:(float)floatStuff;
#end
What this does is declare a set of method calls that an object adopting the protocol has to conform to (the compiler will actually enforce this).
So your SimpleQuery object will hold on to something like the delegate pointer, which you might declare like this among the ivars:
NSObject<QueryCompleteHandlerProtocol> *callback;
What this tells the compiler is that callback is an object that descends from NSObject and adopts the QueryCompleteHandlerProtocol protocol. Sometimes you see this written as:
id<QueryCompleteHandlerProtocol> callback;
When you want to call the callback there's nothing special about them, SimpleQuery's methods will just call:
[callback queryType1Complete:1];
[callback queryType2Complete:2.0];
Finally you client for the procotol class will declare itself as adopting the protocol:
#interface MyClass : NSObject<QueryCompleteHandlerProtocol>
...
#end
And will set itself as the callback with some code like:
[lookup setCallback:self];
This is where the compiler checks that MyClass conforms to QueryCompleteHandlerProtocol, meaning it has implemented queryType1Complete: and queryType2Complete:.
I'm not sure I understand the problem here. Can't SimpleQuery's user just set another delegate object for the second query, or branch on the simpleQuery: parameter? That's a basic part of the delegate pattern, just like having two UIActionSheets for one view controller.