• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Why so many public properties all up in my grizzle?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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

 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

  • Follow-Ups:
    • Re: Why so many public properties all up in my grizzle?
      • From: Simon Wilson <email@hidden>
    • Re: Why so many public properties all up in my grizzle?
      • From: William Squires <email@hidden>
  • Prev by Date: test post
  • Next by Date: Re: Xcode 4.3.1 memory usage
  • Previous by thread: test post
  • Next by thread: Re: Why so many public properties all up in my grizzle?
  • Index(es):
    • Date
    • Thread