views:

1258

answers:

2

Let's say we have a first Object 'Controller' and it initializes another object named 'Tasks' while passing 'self' for reference. Tasks object can now communicate and send messages to the super 'Controller' object. Is this correct for communicating between objects? Is this how its usually done? I've just started to really learn about programming so Im wondering if this is ok. Up until this point, I've relied on delegates and notifications. Is this good practice?

Example:

// Controller Object
task = [[Task alloc] initWithController: self];
- (void) runMethod: (NSString *) incoming {
NSLog(@"%@", incoming);
}

// Task Object
- (id) initWithController: (Controller *) ctrlr {
controllerPointer = ctrlr;
[controllerPointer runMethod:@"hello"];
return self
}


// All this should print out "hello"

And are there any other ways of communicating, interacting between objects?

+2  A: 

Is this good practice?

Sure. There's nothing wrong with doing that.

If you're not using GC, you need to think about whether you want to have your Task object retain your controller object, but in the example you've given, you almost certainly don't want to, since your Controller object will be retaining your Task object and you don't want a retain cycle.

A minor style comment: I wouldn't use controllerPointer as a variable name. I'd just use controller.

And are there any other ways of communicating, interacting between objects?

Well, you've described using notifications which is appropriate if a number of objects, rather than one specific one, might be interested in the notification. Delegates are appropriate if the Task object really doesn't care what kind of class the delegate is.

Another approach that sometimes makes sense is if Controller is a singleton, in which case you could do this from your Task object.

[[Controller sharedInstance] runMethod:@"hello"];

Having said that, I think it's better practice to store the controller as a variable.

Chris Suter
+4  A: 

This is not the usual way that controller objects (Controller in your example) and model objects (Task) typically interact. There are a wide variety of interpretations of the Model-View-Controller (MVC) pattern, but generally speaking, controller objects observe or query the model objects, rather than relying on the models to know who their controllers are and expecting them to communicate directly with them.

Your design creates an unnecessarily tight linkage between the model and controller objects. What happens in the future if, for example, you decide to add a second controller to manage a different view of tasks? Will your Task objects have to manage communications with multiple controllers? That could end up being a lot of code to write if you have a significant number of model objects.

In Cocoa, there are two main ways for model objects to announce events of interest to the rest of the program: notifications and key-value observing (KVO). Notifications are dead simple. You create notifications with a name and the relevant model object, then post it to a shared NSNotificationCenter. From there, the notification center is responsible for delivering the messages to any objects that subscribe to them.

KVO is a bit more difficult to explain. Essentially, behind the scenes, Cocoa has a mechanism for detecting changes to objects and sending updated values directly to classes that observe them. (KVO also serves as part of the foundation of Cocoa Bindings, which are unfortunately not present in the iPhone SDK)

What these two techniques both have in common, though, is that they provide a generic mechanism for informing any other objects that something of interest has happened in a model object. How those objects choose to respond is entirely its own decision.

This separation makes the controller objects and model objects less dependent on one another, and it means that you, as the programmer, can worry less about the specific interactions between the controller and model layers.

Alex