views:

79

answers:

5

I got a view controller class (MyViewController) that deals with a UIView subclass (MyView). I don't want to let any class except the view controller class know about the UIView subclass, so I cannot import MyView.h in MyViewController.h.

So, in MyViewController.m, I put

#import "MyViewController.h"
#import "MyView.h"

@interface MyViewController (PrivateObjects)

MyView *myView;

@end

...

However, to get feedback from MyView, I use a delegate. That delegate has to implement the MyViewDelegate protocol.

How can I implement the MyViewDelegate protocol inside MyViewController without having to #import MyView.h in MyViewController.h?

A: 

Create a protocol (.h) outside of MyView.h and use that in the declaration (.h) of MyViewController, for example:

#import "MyViewDelegate.h"
@interface MyViewController : UIViewController <MyViewDelegate>

--Frank

Frank C.
What if the delegate contains a method `- (void)myView:(MyView *)myView textDidChange:(NSString *)text`?
+2  A: 

You can use a forware-declaration in MyViewController.h

@class MyView;

@interface MyViewController {
    MyView *myView;
}

@end
nils
A: 

Why do you even want to use a protocol? Just put the methods in your PrivateObjects category.

Edit: Apple refers to this technique as "informal protocol"

Pumbaa80
Because "just putting the methods there" is bad programming style, plus `MyView` should be reusable, so a delegate is definitely useful here.
Aha, looks like I misunderstood "I don't want to let any class except the view controller class know about the UIView subclass"
Pumbaa80
+1  A: 

I know it my sound strange, but by experience I can tell you to don't bother so much about privacy hierarchies in Cocoa.

So in an app or in internal frameworks simply document the class stating how it should used.

That's because you cannot have real privacy as long C pointers are around so Objective-C was designed with no syntax that would only give you some illusion of it.

For example the IB outlet variables of view controllers should typically only be accessible by the controller itself, but they are always public, because they must be accessible from the classes that unarchive and instantiate the nib files and link the outlets with the corresponding instances.

[including suggestions from bbum below]

IlDan
It isn't that the language is inadequate in its support for private implementations, it is very much that the language is designed to *not* waste syntax on creating the illusion of privacy, which is all you'd have in a C based language anyway.
bbum
+1  A: 
@interface MyViewController (PrivateObjects) <MyViewDelegate>
....

(BTW, you can't declare a new ivar in a category.)

KennyTM