Why so many public properties all up in my grizzle?
Why so many public properties all up in my grizzle?
- Subject: Why so many public properties all up in my grizzle?
- From: Brian Lambert <email@hidden>
- Date: Fri, 16 Mar 2012 14:00:02 -0700
I’ve been developing iOS applications full-time for about 6 months now and
I love it. I feel pretty strong on the platform now.
I have a lingering question about something that’s really been bugging the
heck out of me, though, that I thought I would ask the list and get some
feedback on.
It seems to be the case that when people are developing a UIViewController
subclass or a UIView subclass that they expose *all* the implementation
details of that class through public properties vs. using ivars.
Here’s an example. For the purpose of this post, I’ve wrote a simple iPhone
app with one view. The link below is a screen shot of it:
https://s3.amazonaws.com/Softwarenerd/MyApp.jpg
For now, I used Interface Builder to generate the UI. In doing so, I wound
up with:
#import <UIKit/UIKit.h>
// MyViewController interface.
@interface MyViewController : UIViewController
// Properties.
@property (weak, nonatomic) IBOutlet UILabel * labelMyLabel;
// buttonDoItTouchUpInside action.
- (IBAction)buttonDoItTouchUpInside:(id)sender;
@end
This means that my UILabel called labelMyLabel is publicly available.
Anyone who has access to an instance of MyViewController can do anything
they want to with my label, including replacing it.
Also, anyone who has an instance of MyViewController can call my
buttonDoItTouchUpInside action.
For example, in my AppDelegate, I can do:
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen]
bounds]];
MyViewController * myViewController = [[MyViewController alloc]
initWithNibName:@"MyViewController" bundle:nil];
[self setMyViewController:myViewController];
[[self window] setRootViewController:[self myViewController]];
[[self window] makeKeyAndVisible];
// Mess with MyViewController!!!! HAHAHAHA FU, MyViewController!!!!
[[myViewController labelMyLabel] setText:@"This is ridiculous!!!!"];
return YES;
}
To me, this totally ridiculous. It breaks well-established rules of
encapsulation.
From my analysis, it appears to be nothing more than an artifact of how
rehydrating NIBs works, and it totally compromises good OO software design
by leaking all the implementation details of MyViewController to the
outside world.
Everyone, all the books, training materials, samples, and so on, just seem
to accept this style of doing things as being normal. In fact, one book I
read *encouraged* this technique of using public properties for ALL the
internal state of a class over using ivars. It said public properties were
preferable.
What in the world is the deal with this?? :-) Can anyone explain this do
me?
Building this class without Interface builder, here’s how I coded it:
// MyViewController implementation.
@implementation MyViewController
{
@private
UILabel * labelMyLabel_;
UIButton * buttonDoIt_;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[[self view] setBackgroundColor:[UIColor whiteColor]];
labelMyLabel_ = [[UILabel alloc] initWithFrame:CGRectMake(20.0, 20.0,
280.0, 21.0)];
[labelMyLabel_ setText:@"I dare you to press Do It!"];
[[self view] addSubview:labelMyLabel_];
buttonDoIt_ = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[buttonDoIt_ setFrame:CGRectMake(20.0, 49.0, 72.0, 37.0)];
[buttonDoIt_ setTitle:@"Do It" forState:UIControlStateNormal];
[buttonDoIt_ addTarget:self action:@selector(buttonDoItTouchUpInside:)
forControlEvents:UIControlEventTouchUpInside];
[[self view] addSubview:buttonDoIt_];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
// buttonDoItTouchUpInside action.
- (void)buttonDoItTouchUpInside:(id)sender
{
[labelMyLabel_ setText:@"You pressed Do It!"];
}
@end
To me, this is how things should be. The implementation details of how my
view works are hidden.
Am I missing something?
@property sure is convenient, but it seems to be misused a lot. A class
should expose properties that are public, and hide implementation details
that are not.
Thanks!
Brian
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden