2

I'm confused with the usage of properties in Objective-C. If I create a new IBOutlet like this:

IBOutlet UISlider *uploadSlider;

And then define a property for the slider so I can use its getters and setters:

@property (nonatomic, strong) IBOutlet UISlider *uploadSlider;

And then @synthesize it in the implementation file, what is the proper way to actually use the property? For example, if I want to change the slider's track image, do I call

    [uploadSlider setMaximumTrackImage:[UIImage imageNamed:@"An image"] forState:UIControlStateSelected];

Or:

[self.uploadSlider setMaximumTrackImage:[UIImage imageNamed:@"An image"] forState:UIControlStateSelected];

The method that I prefix with self is only available after defining properties, which makes me think that it is the correct choice. But I don't understand why. Do I even need properties to access these methods?

Also, if I am using dot syntax to get or set information pertaining to an object, must I define properties for the object even though I am not directly accessing one of its instance methods?

The Kraken
  • 3,158
  • 5
  • 30
  • 67
  • Possible duplicate: http://stackoverflow.com/questions/2032826/property-synthesize http://stackoverflow.com/questions/6425588/property-implementation-of-variables-in-objective-c http://stackoverflow.com/questions/2032826/property-synthesize http://stackoverflow.com/questions/806379/whats-the-difference-between-property-and-synthesize http://stackoverflow.com/questions/6112283/question-about-synthesize http://stackoverflow.com/questions/1398305/objective-c-property-access – CodaFi Apr 27 '12 at 01:30

2 Answers2

2

The correct way is with self.

You shouldn't be able to do it the first way if you properly set the synthesize like this:

@synthesize something = _something;

That is because in the first method you are accessing your ivar directly which is something you should try to avoid when using properties.

Forgot to mention.

The dot notation is just a shortcut for the setter and getter methods to make typing of stuff faster. However I really wouldn't recommend you getting used to it since it breaks the consistency of the message like architecture of objective C.

http://weblog.bignerdranch.com/?p=83

BTW, 2 notes:

You don't need to set the ivar yourself, as long as you set it to @property and then to @synthesize xcode will add the ivar for you.

And if you are using the interface builder, just use the assistant editor and control drag the element to the property area in the respective header file. That saves a ton of time.

Pochi
  • 13,391
  • 3
  • 64
  • 104
2

The current best practice is to put this in your .h file if you want it to be publicly available or in an interface section of your .m file if you want it to be private (which maybe what you want). Also, IBoutlet usually use a weak pointer and should be set to nil in your viewDidUnload method.

So, in your .h file if public

 @property (nonatomic, strong) IBOutlet UISlider *uploadSlider;
 //IBOutlet's are usually weak

or in your .m file if private

 @interface
 @property (nonatomic, strong) IBOutlet UISlider *uploadSlider;
 //IBOutlet's are usually weak
 @end

Then, in your .m file you put @synthesize like this

 @synthesize uploadSlider = _uploadSlider;

Which will generate the getter and setter and also an instance variable called _uploadSlider, so that you are aware how you are accessing it.

Then, the correct way to call it is:

[self.uploadSlider]

which is really the same as

[self getUploadSlider]

Also, for your information, when you look in the Apple documentation, anything that is a property should be called using the . syntax and anything else should be called using the message.

Nick
  • 351
  • 1
  • 8
  • Thanks. Why are IBOutlets typically weak? – The Kraken Apr 27 '12 at 00:46
  • 2
    Since they are usually created in the storyboard they have a strong reference from the storyboard view. By making the property weak, they will be deallocated when the view releases their strong reference to them. As a result, in theory, you do not need to set them to nil but most examples do that anyway. – Nick Apr 27 '12 at 00:52
  • To further explain, when you drag a UIObject to a view in storyboards, it adds the UIObject and there is a strong pointer from the view to that object. If you do not create an IBOutlet, it will already be allocated and deallocated when that view is loaded and unloaded. If you create a strong pointer to it, then when you set it, that UIObject will not be deallocated as long as whatever you set it to exists, even if the view is deallocated. Setting the UIObject to nil in viewDidUnload would solve this. If you are creating the UIObject from code, then it should be strong. – Nick Apr 27 '12 at 00:57
  • Great, thanks. I'm using ARC, which obviously does not require objects to be explicitly dealloc'ed. But besides setting all properties to nil (not sure in which method specifically), what other cleanup do I need to do to ensure that I'm quitting the app gracefully? – The Kraken Apr 27 '12 at 00:57
  • 2
    That is a big question! It varies for different things, for IBOutlets dragged into storyboards in UIViewControllers it is to set them as weak properties and then to nil in viewDidUnload. ARC should take care of most of your objects. You don't need to worry about local variables in methods, they end when the method does. In theory, ARC should take care of instance variables as long as you set the property correct. Also, learn about some of the analysis tools so you can see how your app uses memory. Also, check Apples reference for being a responsible background app. – Nick Apr 27 '12 at 01:08
  • Thanks very much. Given your incredible help, I'm going to mark this answer as correct and up vote the other one. Thanks again. – The Kraken Apr 27 '12 at 01:14