It is always bad practice to pass a class-typed pointer in, as you are tightly coupling your objects together (each object needs to know the class of the other, they might as well be a single object). This is what the delegate pattern is for. It minimises the info MyObject needs (minimally, nothing more than a pointer type id
- preferably, a protocol specified by MyObject to offer it some behavioural guarantees)
So to translate your example
MyObject.h
replace...
-(id)initWithViewController:(ViewController*)aViewController;
with...
-(id) init;
(which you can dispense with if you have no further reason to override)
and...
@property (nonatomic, weak) id delegate;
Instantiation in myViewController (which does need to #include MyObject
) ...
MyObject* object = [[MyObject alloc] init];
Followed by
object.delegate = self;
(Note that object
gets a pointer to myViewController without needing to know anything else about it)
Now you can do this from inside object
:
[self.delegate updateButtonValue:@"example"];
However ... you will want to ensure that your delegate can receive the message updateButtonValue
:
To do this, you declare a protocol in MyObject.h with the signature of this method
@protocol MyObjectDelegate
- (void) updateButtonValue:(NSString*)string;
@end
And in your viewController, declare that you conform to this protocol using <> in the interface line
@interface ViewController <MyObjectDelegate>
(this is no big deal, ViewController already has to #include MyObject
to alloc/init it, so needs no more info to do this)
And expand your property declaration thus:
@property (nonatomic, weak) id <MyObjectDelegate> delegate
Now you have given the compiler enough information for it to ensure that you can only pass conformant messages around. The brilliant thing here is that MyObject can confidently pass messages to MyViewController without needing to know anything about MyViewController other than that it is reached via the delegate pointer.