I'm trying to do something along the lines of:
in some object A:
UITableVIewController *viewController;
[someObjectB setupView: viewController];
in some object B:
-(void) setupView:(UIViewController*)view
{
if the pointer passed in is of type UITableViewController then ...
say, for instance with: [[view class] isKindOfClass [UITableViewController class]]
or: [view isKindOfClass [UITableViewController class]]
}
However, I have two problems: First, the fact that the parameter enters the method in B as UIViewController which is a superclass of UITableView (which I'm doing because this method will also configure other types of view controllers). So I'm wondering, if I pass in UITableViewController to a method parameter of type UIViewController, isKindOfClass still does dynamic binding right? That is, the runtime checks the type of the content, regardless of the static type of the pointer?
Second, notice I did not initialize the pointer in object A before passing it to B. I actually want B to initialize it. But then buy question becomes, how do I test the static pointer type on an uninitialized pointer? That is, inside B: [view isKindOfClass [UITableViewController class]] gives me a BAD_EXEC. My guess, because I'm obviously trying to access a jul pointer. So is there a way to still test based on the pointer static type declaration?
ADDENDUM: (cause I added it as a comment instead, sorry)
Let me rephrase that part of the question in more specific terms: I want obj B to create a variable of type UITableViewController, pass it to A and have A realize it's been given a pointer to UITableViewController, so that it can actually initialize this pointer to a specific subclass of UITableViewController and then obj B pass that now initialized object to some other object.
My reasoning behind wanting to do this is the following scenario: I have a navigationController-based app. It's got a root controller with buttons and depending which button is pressed, the root controller instantiates and pushes table controllers for different tables of a database and, in turn, when clicking on a row of those tables, the tables instantiate and push a detailed view controller.
So far so good, but because of the nature of the project, I want to keep the whole navigationcontroller instantiate-push chain agnostic to the fact that there's a database and that the tables and detailed-view controllers are actually specific subclasses of UITableViewController and UIViewController, respectively.
This means the flow would be:
1- On click, root controller passes generic UIViewController to my custom main controller.
2- This main controller realizes it's been passed a generic table, initializes it to a specific subclass defined by me and does a few things to provide it with data from the sql database.
3 - The root controller, not caring whether the generic UIViewController is a table or not or even a subclass of UIViewController, merely pushes it to the navigationController.
The idea, also, is that then I don't need to include headers for the table subclasses in the root controller. Only the custom main controller knows about these.
So, at the end of the day, the way I see of doing it is by being able to determine what is the type of the pointer being passed, regardless of whether this pointer is nil, points to garbage or points to an actual object. Meaning:
UIVIewController* a -> static type declaration, determined at compile time.
a = [some subclass of UIVIewController alloc] init]; -> dynamic type of the pointer's content, determined at run time, probably by following links through activation records.. similar to "virtual" in C++
As others have pointed out, what you are asking for is impossible. When you pass a variable to a method, it only sends the value, not the type. Also, the runtime has no knowledge of a variable's type within a method. Any variable type handling is done by the compiler. The runtime can only know the class of an object which a variable holds.
As an alternative, if you can change the signature of your method, you could add a parameter which indicates the type of object to create. The calling method still doesn't need to know the exact type of the object, just whether it is a table view controller or not. Here is an example which uses an enumeration to hold the different types.
Used like:
In answer to your first question, yes - Objective C will determine the class type of your object at runtime (dynamically). In answer to your second question, any method call dispatched to a nil object is silently ignored, so none of your class checks will actually work. You should not get a BAD_EXEC however, unless you:
* EDIT *
Added a scenario in which you would get a BAD_EXEC, and also, see the link below for a couple of gotchas in testing for class equality, particularly with the
isKindOfClass
method.In Objective-C, what is the equivalent of Java's "instanceof" keyword?
Objective-C is a pass-by-value language, just like C. You can't initialize
viewController
in your object A with the code you have there. Initialize it, pass its address tosetupView:
, and then initialize it as necessary:and: