Objective C delegate - why specify an instance in the first part of function definition? - objective-c

I'm confused as to what the first part of the following function declaration means. It adds an object instance as part of the function definition.
E.g. In some sample code, class ItemsViewController which derives from UITableViewController has this function definition:
-(void) tableView:(UITableView*) aTableView didSelectRowAtIndexPath:(NSIndexPath*) indexPath
{ ... }
What exactly does the tableView:(UITableView*) aTableView bit achieve?

It allows your delegate to serve as the delegate for multiple UITableViews. When an event happens on any of the UITableViews, the appropriate delegate method gets called and you can use the first parameter to determine which UITableView the event relates to, and act accordingly. (Of course, your delegate has to have some way of knowing which view is which, for instance by having outlets to each of the views that it's the delegate for.)

Related

Is it possible to initialize a property in a category before any category method is called?

Is it possible to initialize a property in a category?
For example, if I have a mutable array property called nameList in a class. Is it possible to have a category created for this class to add an object to the array property before any of the category method is called?
If I understand you correctly, and others are interpreting your question differently, what you have is:
A class with a property
A category on that class
And you want to call a particular method automatically before any category method is called on a given instance, that method would "initialise" the category methods by modifying the property.
In other words you want the equivalent of a subclass with its init method, but using a category.
If my understanding is correct then the answer is no, there is no such thing as a category initializer. So redesign your model not to require it, which may be to just use a subclass - as that provides the behaviour you are after.
The long answer is you could have all the category methods perform a check, say by examining the property you intend to change to see if you have. If examining the property won't determine if an object has been "category initialized" then you might use an associated object (look in Apple's runtime documentation), or some other method, to record that fact.
HTH
Addendum: An even longer/more complex solution...
GCC & Clang both support a function (not method) attribute constructor which marks a function to be called at load time, the function takes no parameters and returns nothing. So for example, assume you have a class Something and a category More, then in the category implementation file, typically called Something+More.m, you can write:
__attribute__((constructor)) static void initializeSomethingMore(void)
{
// do stuff
}
(The static stops the symbol initializeSomethingMore being globally visible, you neither want to pollute the global name space or have accidental calls to this function - so you hide it.)
This function will be called automatically, much like a the standard class + (void) initialize method. What you can then do using the Objective-C runtime functions is replace the designated initializer instance methods of the class Something with your own implementations. These should first call the original implementation and then an initialize your category before returning the object. In outline you define a method like:
- (id) categoryVersionOfInit
{
self = [self categoryVersionOfInit]; // NOT a mistake, see text!
if (self)
{
// init category
}
return self;
}
and then in initializeSomethingMore switch the implementations of init and categoryVersionOfInit - so any call of init on an instance of Something actually calls categoryVersionOfInit. Now you see the reason for the apparently self-recursive call in categoryVersionOfInit - by the time it is called the implementations have been switched so the call invokes the original implementation of init... (If you're crosseyed at this point just draw a picture!)
Using this technique you can "inject" category initialization code into a class. Note that the exact point at which your initializeSomethingMore function is called is not defined, so for example you cannot assume it will be called before or after any methods your target class uses for initialization (+ initialize, + load or its own constructor functions).
Sure, it possible through objc/runtime and objc_getAssociatedObject/objc_setAssociatedObject
check this answer
No it's not possible in objective c.Category is the way to add only method to an existing class you can not add properties in to this.
Read this
Why can't I #synthesize accessors in a category?

How can a superclass trigger an action in a subclass in objective-c?

So I have a tab-bar controller where each tab is a UITableView that extends from a superclass that I created. This superclass (obviously) extends UITableViewController.
Each UITableViewController represents a tabbed view and has its own model that pulls data that is specific to each TableView, so I need to separate these methods and variables from the superclass.
However, I have implemented "pull-to-refresh" in my superclass and would like to refresh the data that is held by the subclass from the update method that is called when pulling-to-refresh.
Do I basically have to cut my losses and implement pull-to-refresh individually within every UITableViewController in my tabbar, or is there a way of getting the update command to call a method inherent (but implemented differently) within each UITableViewController in my tabbar?
In your common superclass, create a method
-(void)onRefresh {
}
that does nothing. Call this method when you need to trigger an action in a subclass.
In each of your subclasses, implement a method with the same signature. These methods would be called when superclass calls
[self onRefresh];

Call method in UITableViewController from custom UITableViewCell

I need to call a method and pass an object from my custom UITableViewClass implementation to my UITableViewController class. I realize creating an instance of the tableViewController in the custom tableViewCell and calling tableViewController's method is a bad practice.
What is the proper way of doing this?
Two magical concepts in Objective-C are Delegation and Notifications.
Delegation allows you to have your controller hook into a weak object referenced in the cell, which avoids a retain cycle, while still allowing you to send messages to it.
Notifications allow your Cell to broadcast a general notification to any classes that are active and listening for it.
Pick one, and whichever is easiest, stick with it. The two are basically equal in this situation.
Having a reference of the tableController inside the cell is indeed Bad practice
You could fix this by implementing a special #protocol for your UITableViewClass
And add a delegate method to it, and then implment the method inside UITableViewController, and since your UITableViewClass delegate is your UITableViewController, then you would call it like
in your UITableViewClass.m
[delegate someMethod:data];

i need help understanding a few methods in a view based application

when i create a new view based application a few methods in the implementation file (.h)
i do not understand their purpose and when i look into the developer center its kind of hard to understand because of how its explained.
what purpose do these methods have and what are they used for in plain english.
- (void)loadView
- (void)viewDidLoad
- (void)viewDidUnload
what im guessing the viewdidload is , is that when the view is loaded and anything between the braskets are executed first, but when there are other custom methods created (if that is the purpose of viewdidload) how does it know which method to execute? is the code executed from top to bottom? being that whatever method is listed first is executed?
also i have noticed the word super inside brackets along with other keywords. what is the purpose of super?
thank you!
Well, "super" means Super Class, or the parent class that your current class extends.
#interface MyViewController : UIViewController{}
In the code above, that you can find in some .h files, MyViewController extends UIViewController. So, all the time that you call "super" inside MyViewController, you are calling the UIViewController.
So, when you see the following structure, inside MyViewController...
- (void)viewDidLoad {
[super viewDidLoad];
.
.
.
.
.
}
... it means that when the method "viewDidLoad" is called, it will first call the method from it's super class, to after run it's own code.
if you let the whole viewDidLoad method commented, it means that the parent method will be called automatically, because you are not overwriting it like on the previous example.
To understand what all the methods (loadView, viewDidLoad, viewDidUnload), take a look at the UIViewController Class reference on Apple Developer Connection.
Cheers,
VFN
Your class is a derivative of the system class UIViewController (is a subclass, in Objective C lingo). [super someMethod] means - call this method for the base class (superclass in ObjC lingo).
If you're familiar with C#, super in ObjC means same as base in C#. And the same as super in Java. :)
The system-provided UIViewController class has loading functionality in its loadView method. This method is called by the system, and it does a lot of work. The viewDidLoad method, on the other hand, is defined in the base class but does not do much. Its purpose is that you can override it and provide your own functionality there. Same for viewDidUnload.

In Objective-C, do I redirect a containing instance's method without subclassing it?

In Objective-C, how do you rewire a class's instance method to call a method in another class?
Say a UIView class A contains another UIView class called childA. I want it so that when childA's drawRect is called, a method in class A is invoked without having to subclass childA and do the desired call in its drawRect there. How can this be achieved?
Also, how do I supply a method to childA's draw class dynamically? I know this is probably not a good practice but it would be useful for testing purposes.
To answer your first question about rewiring methods:
You don't want to be doing this on general principle, since it kinda defeats the whole purpose of object-oriented design, but for testing purposes, it can be useful. As long as you're on Leopard, it's not especially difficult, either.
Take a look at the Objective-C 2.0 Runtime Reference, which contains the keys to the kingdom, as it were. Look at the functions class_getInstanceMethod, method_getImplementation, method_getTypeEncoding, and class_addMethod which, in combination, let you change the methods of a class at runtime.
If you're just swizzling one selector for another, method_exchangeImplementations is a useful shortcut.
To answer your second question about supplying a method dynamically, that's as simple as passing a SEL to a method and then calling -performSelector:withObject::
#interface MyView : NSView {
SEL drawingSelector;
id drawingDelegate;
}
#property SEL drawingSelector;
#property id drawingDelegate;
#end
#implementation MyView
- (void)drawRect:(NSRect)rect {
[self.drawingDelegate performSelector:drawingSelector withObject:[NSValue valueWithRect:rect]];
}
#end
For the first issue you raise, it seems like you would set up UIView A as a delegate object of childA and the other UIViews - then they could use delegate methods to call the extra drawing features you wanted in A.
Either that or have each child ask for the superview and if it is of type "A" call the method you are interested in.