Properties and Objective-C 2.0...

Discussion in 'iOS Programming' started by ArtOfWarfare, Aug 13, 2008.

  1. ArtOfWarfare macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #1
    Ok, so I've read The C Programming Language and Learning Cocoa in the interests of learning how to program for the iPhone. Unfortunately... it would appear there's still just a bit more to learn before I can start doing some real programming.

    What are Properties and how do they fit in with everything else I learned from the other two books? I've read the ADC summary of properties... but it doesn't seem to have helped me (it's too much of a summary and it doesn't offer a tutorial so I can build a program myself that makes use of them.)

    I'd like a program where I hit a button, and another button hides. It's not a real program... just something so I can hopefully understand properties better.

    UIView has a property "hidden" according to the documentation in XCode. Can I somehow use the property to make my button hide? And when I hide the button... will that make it stop responding to clicks (sorry, I guess that's touches when you're working on an iPhone program.)

    Thanks in advance for any help people can offer.

    *grumbling* stupid Apple NDA keeping book publishers from helping me understand Objective-C 2.0 and properties...
     
  2. beit macrumors newbie

    Joined:
    May 27, 2008
    #2
    Properties are a small part of objective-c 2.0 and i thik you gonna learn about in no more than a couple of hour :-D
    The idea is that if you have a variable objective-c give you a way to write accessor whitout writing a line of code.
    What you do is creating your variable and tell the compiler that you need this variable for reading and writing, for example, or only for read...and so on
    The compiler than synthesize your variable and prepare accesor method so when you will need to acces them you will do it by

    myVariable.properties

    as you do in Java for example :-D

    this is in a short way properties...If you want more info a suggest you to start here:

    http://en.wikipedia.org/wiki/Objective-C (search about properties)

    or here:

    http://www.theococoa.com/document.page/510

    byyy
     
  3. SwampThingTom macrumors member

    Joined:
    Jul 12, 2008
    Location:
    Fairfax, VA
    #3
    Properties are just a convenient feature to abstract access to member variables and support common getter/setter patterns. When you need to expose access to a variable outside of its class, it is always better to do so via a property. That way if the underlying implementation needs to change, it can be easily done without requiring changes to all code that accesses the variable.

    I don't have the answer to your specific question about the "hidden" property. My suggestion is to write exactly the kind of test app you describe and see what happens. Whenever I've wanted to "hide" a button and have it stop responding to touches, I've used "removeSubview". But it could be that the hidden property does what you want and I've been doing it the hard way! ;-)

    Actually, the NDA applies only to the iPhone APIs, not to Objective C. Properties are just a newer feature of Objective C so they aren't yet covered by most of the books out there.

    Tom
     
  4. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #4
    Properties in Cocoa Touch are no different than properties in standard Cocoa. There are plenty of tutorials and such out there about them, but I will summarize.

    The *old* way of doing things was to use setter and getter methods. For example in Mac OS X Cocoa you will see in NSView.h:

    Code:
    - (void)setHidden:(BOOL)flag;
    - (BOOL)isHidden;
    But with 10.5 and the iPhone, these methods are replaced with properties, which just simplifies things. They handle the internal memory management for you. So let's say I have an accessor for assigning a NSString name variable. The old way would be:

    Code:
    // .h
    - (void)setName:(NSString *)name;
    - (NSString *)name;
    
    // .m
    - (void)setName:(NSString *)aName {
        if (name != aName) {
            [name release];
            name = [aName retain];
        }
    }
    
    - (NSString *)name {
        return [[aName retain] autorelease];
    }
    
    // example
    [myObject setName:@"John Doe"];
    (or some variation of this. It all depends on the variable and how you plan on using it.)

    But now with properties you can replace all that with:
    Code:
    // .h
    @property (readwrite, retain) NSString *name;
    
    // .m
    @synthesize name;
    
    // example
    myObject.name = @"John Doe";
    So you can see it cuts down on code to write. If you have a class with dozens of accessors, it can be a burden to write all that. Properties save you time and code.

    So to set a UIView's hidden property, you do:
    Code:
    view.hidden = YES; // or NO
     
  5. ArtOfWarfare thread starter macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #5
    Thanks all.

    I have a headache right now so I can't really understand what was just said but the beauty of forums is that I can just come right back and reread it all when the headache goes away without having to ask for you to say it again :D

    I think I'll go get some Tylenol.
     
  6. ArtOfWarfare thread starter macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #6
    OK... so I tried this:

    Code:
    // ButtonToggler.h
    
    #import <UIKit/UIKit.h>
    @interface ButtonToggler : NSObject
    
    {
    	IBOutlet	UIButton	*topButton;
    	IBOutlet	UIButton	*botButton;
    }
    
    - (IBAction) toggleBot: (id) sender;
    - (IBAction) toggleTop: (id) sender;
    
    @property(nonatomic, getter=isHidden) BOOL hidden;
    
    @end
    
    // ButtonToggler.m
    
    #import "ButtonToggler.h"
    
    
    @implementation ButtonToggler
    @synthesize hidden;
    - (IBAction) toggleBot: (id) sender
    {
    	botButton.hidden = YES;
    }
    
    @end
    The error that I got and don't understand is...
    The two warnings aren't important... it's just letting me know that the class "ButtonToggler" isn't fully implemented because it's missing the method definition for "-toggleTop:".
     
  7. SwampThingTom macrumors member

    Joined:
    Jul 12, 2008
    Location:
    Fairfax, VA
    #7
    Properties are used as a convenience feature for providing access to member variables without requiring you to write explicit getter and setter methods. So you need a member variable that corresponds to the property. In your case, you need a member variable of type BOOL that is called "hidden". As kainjow showed in his example, the advantage is that this keeps you from having to explicitly write "isHidden" and "setHidden" accessor methods.

    But it's not clear to me how you are planning to use this property in the sample code you provided. Unless you provide your own "setHidden" method, you won't be able to change the "hidden" property of your buttons when your "hidden" property gets set.

    Tom
     
  8. ArtOfWarfare thread starter macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #8
    :confused:

    Okay... so I made a boolean variable... but it's still not working.

    Code:
     // ButtonToggler.h
    
    #import <UIKit/UIKit.h>
    @interface ButtonToggler : NSObject
    
    {
    	IBOutlet	UIButton	*topButton;
    	IBOutlet	UIButton	*botButton;
    	BOOL				botHidden;
    }
    
    - (IBAction) toggleBot: (id) sender;
    - (IBAction) toggleTop: (id) sender;
    
    @property(nonatomic, getter=isHidden) BOOL botHidden;
    
    @end
    
    // ButtonToggler.m
    
    #import "ButtonToggler.h"
    
    
    @implementation ButtonToggler
    @synthesize botHidden;
    - (IBAction) toggleBot: (id) sender
    {
    	botButton.botHidden = YES;
    }
    @end
    My error now is...

    :confused:

    botButton is the outlet... so... that doesn't work. I... I...

    how do I just hide the dang button? I don't need properties. If setter/getters can be replaced with properties, doesn't that mean it can go the other way around?
     
  9. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #9
    botHidden isn't a property of botButton, that is why you've getting that error. botHidden is your property for your class. A button has a "hidden" property. So it should be:
    Code:
    botButton.hidden = YES;
     
  10. ArtOfWarfare thread starter macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #10
    ...ok...

    well... changing it to what you suggested made it work.

    It's still not making that much sense to me... hopefully if I just keep using it it'll eventually start to make sense to me (like with pointers in C... it took me far longer to understand those then anything else...)

    Edit:

    Now I'm trying to make it actually toggle whether it's hidden or not.

    Code:
    - (IBAction) toggleBot: (id) sender
    {
    	if (botButton.hidden = NO)
    	{
    		botButton.hidden = YES;
    	}
    	else
    	{
    		botButton.hidden = NO;
    	}
    }
    It builds without errors but it doesn't... work. Pressing the first button doesn't hide the other.
     
  11. ArtOfWarfare thread starter macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #11
    OH!

    *dope slap!*

    I don't need to declare @property or @synthesize!

    Those are all in the UIKit!

    But... I still don't understand... how do I find out what the status of hidden is? I want to run an If-Else that will check the status of hidden, and if the object is hidden, it'll reveal it, otherwise, it'll hide it. (In otherwords, it toggles the status of the hidden boolean.)
     
  12. SwampThingTom macrumors member

    Joined:
    Jul 12, 2008
    Location:
    Fairfax, VA
    #12
    You probably need to call setNeedsDisplay for the view containing the buttons.

    BTW, for toggling a BOOL, you can rewrite that if/then/else construct with the much simpler:

    botButton.hidden = ! botButton.hidden;

    Tom
     
  13. ArtOfWarfare thread starter macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #13
    My issue was I had

    Code:
    if (botButton.hidden = YES)
    See the problem?

    Should have been ==

    Well, thanks for all the help!

    I guess I can get started on what I plan to be the first application I'll sell in the application store.
     

Share This Page