Can anyone explain the synthesize process when using Objective-C? - objective-c

I realize that it automatically creates a setter & getter for you but I'm uncertain how the setter actually "looks".
Also, why is it recommended that we say #synthesize someObject = _someObject; instead of just #synthesize someObject;?

Easy bit first: you don't need to #synthesize at all any more. If you have an #property and you don't synthesise it then one is implied, of the form #synthesize someObject = _someObject;. If you left off the = _someObject then you would have the same thing as #synthesize someObject = someObject;. The underscore version is therefore preferred because Apple has swung back to advocating underscores for instance variables and because it's consistent with the implicit type of synthesise.
The exact form of setter and getter will depend on the atomic, strong, unsafe_unretained, etc flags but sample nonatomic strong setter, pre-ARC is:
- (void)setProperty:(NSString *)newPropertyValue
{
[newPropertyValue retain];
[_property release];
_property = newPropertyValue;
}
Note the retain always occurs before the release. Otherwise the following (which you would arrive at in a roundabout fashion rather than ever writing directly):
self.property = _property;
Would lead to _property potentially being deallocated before it was retained.
A sample getter (also pre-ARC) is:
- (NSString *)property
{
return [[property retain] autorelease];
}
The retain ensures that the return value will persist even if the object it was queried from is deallocated. The autorelease ensures you return a non-owning reference (ie, the receiver doesn't explicitly have to dispose of the thing, it can just forget about it when it's done). If the thing being returned is immutable but the instance variable is mutable then it's proper form to copy rather than retain to ensure that what you return doesn't mutate while someone else is holding onto it.

Check leture 3 of iPad and iPhone Application itunes
_someObj replace a memory location for store your object(a pointer).
Xcode 4 auto #synthesize anyObject = _anyObject; -> So you don't need to write #synthesize anymore.
If you have some other object or _anyMemoryLocation write before in your.m file, you can use #synthesize yourObj = _anyMemeryLocation if you don't want rewrite all name in your.m file.
Setter and getter 2 methods use to set or get your object's value outside or inside your class:
-(void)setObject:(ObjectType *) object;
-(void)getObject:(ObjectType *) object;
The key nonatomic auto generate setter and getter for you.
If you want to implement more method went setObject, you can rewrite it in your.m file
-(void)setObject:(ObjectType *) object{
_object = object; //rewrite setter can done anywhere in your.m file
//Add more method
}

Related

Objective C: Differentiating iVars and Accessors

#interface RandomObject : NSObject
{
NSString* someObject; // I know I don't have to explicitly declare. Just to clarify my point.
}
#property (nonatomic, strong) NSString *someObject;
#end
#implementation RandomObject
#synthesize someObject;
#end
Given the code above and Xcode 4.3 is used (hence, no auto-synthesizing), here is my question.
The property/synthesize will create accessors for someObject, namely getter and setter. So if I want to assign a value to someObject, I can do this.
self.someObject = #"Tomato"; // [self setSomeObject: #"Tomato"];
If my understanding is correct, self will send #"Tomato" to setSomeObject method. But what if you do this?
someObject = #"Tomato"; // or maybe _someObject = #"Tomato" if you are doing auto-synthesizing
Directly accessing an iVar object seems like a bad idea, but since someObject is a private variable, within the same class you have access to that, right?
I understand why you would need to use self.someOject if you want to manipulate someObject from another class. But why is it that you'd need to do the same even though you are still in the same class. Why is it that it's a bad idea to directly access iVar.
Generally speaking accessors have more pros than cons and I use them everywhere I can.
The main issue is that every place you reference the ivar directly is another potential place your code will need to change.
For example imagine you have referenced someObject in multiple places throughout your class. Then the requirements change and now you decide that when the value of someObject is assigned you need to so some other work. Due to the fact that you have accessed the ivar directly throughout the class you now have to either duplicate this new code everywhere you assign someObject or refactor. If you was using an accessor you just have one piece of code to change
- (void)setSomeObject:(id)anObject
{
if (anObject != someObject) {
someObject = anObject;
[self doSomeWork];
}
}
You can have the same issue with the getter - imagine you store an array of objects in someObjects - this works great but then later down the line you decide that you don't actually need to store someObjects as it can be dynamically computed from other values. If you have directly accessed the ivar everywhere then this becomes a big chore. If you stick to abstracting someObject behind a getter then all you now have to do is
- (NSArray *)someObjects
{
return [self calculateSomeObjects];
}
This is exactly the idea with non-ARC code, which puts the memory management of the ivar in one place (behind accessors) so that you do not have to litter your code with repetitive code.
The property does more than just assigning an object to the ivar.
If you don't use ARC, the property will auto-generate retain/release code to handle memory management. Just calling someObject = #"Tomato" creates a memory leak (if someObject is assigned)
If your property is atomic, the property will provide thread safety, while accessing the ivar would not be thread safe.
See https://stackoverflow.com/a/589348/1597531 for examples of auto-generated property code.

How does adding a variable as a property affect it?

What difference does it make in memory management to define a variable as a property? For instance:
#interface foo {
NSString *theStr;
}
#end
#implementation foo
- (void)bar {
NSLog(theStr);
}
#end
Versus:
#interface foo {
NSString *theStr;
}
#property(retain) NSString *theStr;
#end
#implementation foo
#synthesize theStr;
- (void)bar {
NSLog(theStr);
}
#end
It seems like the first is autoreleased or something similar, while the second is retained throughout the life of the class. Is that the case, or what is the difference?
If you define a variable just in the interface without defining it as a property (as in your first example) means that you'll have to take care of everything related to memory management yourself. Assigning something to that variable will not retain it automatically, not will setting the variable to something else release the previous value.
Defining it as a property creates getter and setter methods under the hood. Most importantly, if you use it with the "retain" keyword, your setter method will retain the new value (and release the old one if there was one).
Note that the setter method will only be invoked if you use the dot notation, e.g., self.myStr = #"new string", or the method call, e.g., [self setMyStr:#"new string"]. If you just call myStr = #"new string" the setter method will not be called and you need to release the old value yourself and retain the new one.
I don't think the first case shows an autoreleased object, it would all depend on how you managed the creation and the destruction of that particular object. If for instance when you create that object you call:
//This string will indeed be autoreleased
theStr=[NSString stringWithString:#"Jibber jabber"];
//Or even
theStr=#"Jibber jabber";
But you have to take charge of the memory management if you create it in the following way:
//Manage my memory
theStr=[[NSString alloc] init];
//You have to release this property on the dealloc method
-(void)dealloc{
[theStr release];
[super dealloc];
}
On your second example, you create a setter and a getter method for the property theStr and by adding the nonatomic attribute, you make your property not thread safety, meaning that a thread can begin to modify your property while another one is already editing it. And by setting the retain attribute to your property, the setter method will be synthesized the following way:
- (void) setTheStr:(NSString *) newString {
[newString retain];
[theStr release];
theStr = newSupervisor;
}
You can consult more about this in one of my favorite books, Learning Objective-C 2.0 in chapter 12.

Objective-C, interface declarations with properties

In the following common sample,
////
#interface MyObject : NSObject
{
#public
NSString * myString_;
}
#property (assign) NSString * myString;
#end
#implementation MyObject
#synthesize myString = myString_;
#end
////
why declare myString_ in the interface at all?
I ask because we can still get and set myString in the implementation using self.myString, [self myString], self.myString = ... and [self setMyString:...] and in fact we must if instead it's being retained.
This is a matter of preference/convention for some. By default, doing:
#property (assign) NSString * myString;
...followed by:
#synthesize myString;
...will give you three things. You get a setter method that can be accessed as self.myString = #"newValue" or [self setMyString:#"newValue"], a getter method that can be accessed as NSString* temp = self.myString or NSString* temp = [self myString], and an instance variable named myString that be be accessed directly inside of your class (i.e. without going through the getter and setter) and used to set and get the property value, and which is used internally to back the property.
If you like you can do #synthesize myString = someOtherVarName, and then you still get the setters and getters just as before, but instead of the myString instance variable the someOtherVarName instance variable is used to back the property, and no myString variable is created.
So why ever use the more verbose syntax? There is never any case that requires that you do so, but some people prefer to do so when dealing with properties that are declared retain or copy. The reason for this being that setting a property declared retain or copy via its generated setter method will affect the retain-count of the object being set/unset. Doing the same thing by accessing the instance variable directly will not.
So by aliasing the instance variable to something else, you can make a distinction in the code along the lines of "anything that does xxx.myString = Y is modifying the retain count, while anything that does someOtherVarName = Y is not". Again, it's not necessary to do this, but some people prefer to.
You should be able to skip it. Modern compilers allow that.
When you define a property, you are actually declaring how the getter and setter methods are constructed for a particular instance variable. Earlier it needed the instance variable to be defined so you declared it. It also allowed the property name to differ from the instance variable name via #synthesize myProperty = myIVar;. Now you don't need to do this as the modern compilers generate the instance variable for you.
The dot syntax is actually a convenience thing as you would've noticed. It doesn't directly refer to the instance variable but the methods myProperty and setMyProperty:. You can even call myArray.count where count isn't a property (I wouldn't recommend it even though lot of people seem to like it).
While there is a difference between the two, the gap seems to be slowly closing.
That's just a problem about point of view. If you access ivar directly, it's you're accessing it internally. If you're using property, you're not accessing ivar (semantically). You're using accessing method of the object. So you're handling the self as like external object which the internal is unknown.
This is encapsulation problem of Object-Oriented paradigm.
And I recommend some tricks when using properties.
The ivar declaration is optional, not required. Compiler will generate it automatically.
You should set the ivar as #protected or #private to encapsulate it correctly. (at least there is no reasonable reason)
I recommend to use nonatomic if you don't need threading lock when accessing the property. Threading lock will decrease performance greatly, and may cause strange behavior in concurrent execution code.
You can use this code to do same thing.
#interface MyObject : NSObject
#property (assign,nonatomic) NSString * myString;
#end
#implementation MyObject
#synthesize myString;
#end
And this will be transformed roughly something like this.
#interface MyObject : NSObject
{
#private
NSString* myString; // Ivar generated automatically by compiler
}
#end
#implementation MyObject
// Methods with thread synchronization locking generated automatically by compiler.
- (NSString*)myString { #synchronized(self) { return myString; } }
- (void)setMyString:(NSString*)newMyString { #synchronized(self){ myString = newMyString; } }
#end
In fact, I'm not sure about synchronization lock with assign behavior directive, but it's always better setting it nonatomic explicitly. Compiler may optimize it with atomic operation instruction instead of locking.
Here is reference document about the properties: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html%23//apple_ref/doc/uid/TP30001163-CH17
With the modern Obj-C runtime, declaring the ivar is more of a formality than anything else. However, there are some memory management things to keep in mind.
First, the property declaration for an object type is usually retain, or for strings it may be copy. In either case, the new object is retained.
Given the following code:
NSString *string = [[NSString alloc] init];
myString_ = string;
self.myString = string; // If the property was retain or copy
The second assignment would leak; the first would not. This is because the property would retain something that already has a retain count of 1—it is now at 2. When you release the property in dealloc, the count goes to 1, not 0, so it won't be released. With the first option, however, the retain count stays at 1, so dealloc brings it down to 0.
In your example, leaving the property as assign will make the ivar declaration a formality.

IBOutlets, instance variables and properties: Best Practices

I've done all sorts of research today on best practices with regards to declaring IBOutlets and instance variables, managing them, using the correct accessors and properly releasing them. I'm pretty much there, but I've got some niche questions that I hope somebody will be able to advise the best practice on. I'll format them as code and comment the questions so as to make it easier to understand. I've excluded some obvious parts that I didn't think were relevant and can be safely assumed to work (like pre-processor stuff, #end, required implementation methods etc).
MyViewController.h
#class OtherViewController;
#interface MyViewController : UIViewController {
NSString *_myString;
BOOL _myBOOL;
}
// The first two properties aren't declared in the interface
// above as per best practices when compiling with LLVM 2.0
#property (nonatomic, retain) OtherViewController *otherViewController;
#property (nonatomic, retain) UIButton *myButton;
#property (nonatomic, copy) NSString *myString;
#property (readwrite) BOOL myBOOL;
MyViewController.m
#implementation MyViewController
// Synthesizing IBOutlets on iOS will cause them to be
// retained when they are created by the nib
#synthesize otherViewController;
#synthesize myButton;
// Assign instance variables so as to force compiler
// warnings when not using self.variable
#synthesize myString = _myString;
#synthesize myBOOL = _myBOOL;
- (void)viewDidLoad {
// QUESTIONS:
// 1. Ignoring convenience methods, can you still alloc and init in dot notation
// even when it's being properly synthesized?
self.myString = [[NSString alloc] initWithString:#"myString"];
self.myString = existingNSStringObject;
// 2. Should you always call methods for IBOutlets and instance variables using dot notation?
// Is there any difference seeing as these aren't directly invoking setters/getters?
[self.myButton setText:self.myString];
[myButton setText:self.myString];
[self.otherViewController.view addSubview:mySubview];
[otherViewController.view addSubview:mySubview];
[self.myButton setAlpha:0.1f];
[myButton setAlpha:0.1f];
self.myButton.alpha = 0.1f;
myButton.alpha = 0.1f;
// 3. How fussy are scalar variables in terms of getters and setters,
// given that there is a #synthesize declaration for them?
self.myBOOL = YES;
myBOOL = NO;
if(self.myBOOL) { ... }
if(myBOOL) { ... }
// 4. On instantiation of new view controllers from NIBs, should you use
// dot notation? (I haven't been doing this previously).
otherViewController = [[OtherViewController alloc] initWithNibName:#"OtherView" bundle:nil];
self.otherViewController = [[OtherViewController alloc] ... ]
}
- (void)viewDidUnload {
// 5. Best practice states that you nil-value retained IBOutlets in viewDidUnload
// Should you also nil-value the other instance variables in here?
self.otherViewController = nil;
self.myButton = nil;
self.myString = nil;
}
- (void)dealloc {
[otherViewController release];
[myButton release];
[_myString release];
}
I always declare and explicitly set a property's underlying instance variable. It's a little more work up front, but in my mind it's worth it to explicitly differentiate variables and properties and see at a glance what instance variables a class has. I also prefix instance variable names, so the compiler complains if I accidentally type property instead of object.property.
Calling alloc / init creates an object with a retain count of 1. Your synthesized property will also retain the object, causing a memory leak when it's released (unless you release your property right after, but that's bad form). Better to alloc / and release the object on a separate line.
Dot notation is effectively the same as calling [self setObject:obj]. Not using dot notation accesses the underlying instance variable directly. In init and dealloc, always access the instance variable directly as the accessor methods can include extra operations (such as key value observing notifications) that are not valid when the object is being created or destroyed. All other times use the synthesized accessor methods. Even if you're not doing anything special now, you might later override these methods later to change what happens when the variable is set.
Scalars work the same way, only you don't have to worry so much about memory.
One accesses the synthesized accessor methods, the other accesses the instance variable directly. See questions one and two again, and be careful about memory leaks!
The view controller may be pushed onto the screen again, in which case your viewDidLoad method will be called a second time. If you're setting initial values in viewDidLoad, go ahead and set your properties to nil here. This makes sense for properties that use a lot of memory and aren't going to affect the state of the view. On the other hand if you want the property to persist until you're sure it's no longer needed, create it in your init method and don't release it until dealloc.
1) You've slightly misunderstood #synthesize. #synthesize does nothing with the object. It only tells the compiler to generate the getter and setter methods according to the options used in your #property declaration
// Synthesizing IBOutlets on iOS will
cause them to be
// retained when they
are created by the nib
The outlets aren't retained (outlets are just notices to interface builder and don't affect the code), the objects are retained when the setter generated by #synthesize is used. When the nib is loaded, the loading system calls your generated setter.
2) Deciding whether to use accessors in objective C is no different from deciding to use accessors in any other object oriented language. It is a choice of style, need and robustness. That the accessor is serving as an IBOutlet makes no difference.
But in objective C I would suggest you should NOT use accessors in two places: dealloc and within the var's accessor method itself.
And if you ARE using the accessors in init then you need to be careful about your retain counts.
self.myString = [[NSString alloc] initWithString:#"myString"];
This line leaks memory. Using your copy accessor retains the object, so you should release it here after creating it.
3) Not sure what you mean by fussy. Possibly see answer to 2)
4) See 2) and be careful about memory management. If you call alloc/init you are now responsible for releasing the object - this is entirely independent of the retains/releases used by accessors and dealloc.
5) No, you should not nil other instance variables in viewDidUnload. Your controller is expected to maintain its state even if the view goes away. viewDidUnload is only for cleaning up potentially memory-heavy view objects when the controller's view is not currently on screen.
Consider a navigation controller. View controller 1 is on the stack and then view controller 2 is pushed and is now visible. If memory conditions get low, the system could attempt to unload view controller 1's view and will then call viewDidUnload.
Then popping view controller 2 will not create the view controller 1 object again, but it WILL load view controller 1's view and call viewDidLoad.
Re comments
2) That's exactly right - you can use a convenience constructor or release immediately after your alloc/init and assignment, or release before the block exits, or autorelease. Which you choose is mostly a matter of style (though some would argue against autorelease - but not me!)
3) There are accessors for scalars - you have created some in your code
#property (readwrite) BOOL myBOOL;
This creates methods myBOOL and setMyBOOL on your class.
Remember that there is nothing special about dot notation. It is only a convenience and when the code is compiled myObject.property is exactly equivalent to [myObject property] and myObject.property = x is exactly equivalent to [myObject setProperty:x]. Using dot notation is purely a style choice.
Dot notation and brackets notation are pretty much the same.
By self.myVariable you are accessing the getter of the property of the instance variable myVariable and by myVariable you are accessing the local variable. They're not the same thing.
You can customize the setters and the getters by overriding the methods and specific some certain conditions for them.
See first answer ( brackets are preferred - better understanding of the code )
Better make a separate method.
Like:
- (void) releaseOutlets {
self.firstOutlet = nil;
self.mySecondOutlet = nil;
……………………
self.myLastOutlet = nil;
}
and then call this method both in viewDidUnload and in dealloc methods.
Hope it helps !

Objective-C 2.0; Assigning a Property; Leaking Memory?

I'm still learning about Objective-C memory management. I'm trying to implement several simple classes in an example program that I'm building.
As an example, say I have the following class definition:
#import <UIKit/UIKit.h>
#interface customViewController : UIViewController
{
customObject *myCustomObject;
}
#property (retain) customObject *myCustomObject;
- (void)replaceCustomObject:(customObject *)newObject;
#end
For the property, I use the standard synthesize keyword...
#synthesize myCustomObject;
Then please assume that in the instance of customViewController the myCustomObject is already set with a valid value and is in use. Then the method replaceCustomObject is defined as:
- (void)replaceCustomObject:(customObject *)newObject
{
//Does this cause a memory leak because I just assign over
//the existing property?
self.myCustomObject = newObject;
}
As the comment asks, does this leak memory? Or is this the valid way to replace a previous object with a new object?
Thank you,
Frank
As others have mentioned, your code is perfectly valid and won't leak memory when assigning to the property.
If you have forgotten to implement a proper dealloc method, the last object assigned will be leaked when your customViewController is destroyed. A proper dealloc implementation would look like so:
- (void)dealloc
{
self.myCustomObject = nil;
[super dealloc];
}
That's perfectly valid, and does not leak memory. The synthesized accessors manage retain counts correctly.
(As an aside, you don't need that replaceCustomObject: method; since your property is readwrite by default, you have an auto-generated setCustomObject: method that clients of your class can use, and which follows the normal Cocoa naming conventions.)
According to this, if you use (retain) in your declaration, the synthesized method will release the old value first, then retain the new one:
if (property != newValue) {
[property release];
property = [newValue retain];
}
the property accessor syntax
self.x = y;
has the same effect as calling the setter method explicitly:
[self setX:y];
The accessor method will do whatever it has been written to do. In your case, for a #property(retain) property that has been #synthesized, the accessor will release the old object and retain the new one.
So, calling the setter, whether explicitly or through the '.' syntax, will do the right thing - including the right memory management.
So in short: no, this will not leak memory.