override getter only needs #synthesize - objective-c

I want to ovveride getter for lazy instantiation and leave default setter.
Do I need #synthesize ?
Why ?
#interface Foo()
#property (strong, nonatomic) NSObject *bar;
#end
#implementation Foo
- (NSObject *)bar
{
if(!_bar) _bar = [[NSObject alloc] init];
return _bar;
}
#end
Update: I've changed variable and class name, because it was confusing. From Deck and card to Foo and bar.

No, you only need to explicitly synthesize (to get the synthesized ivar) if you explicitly implement all of the accessor methods (both getter and setter for readwrite properties, just the getter for readonly properties). You've written the getter for this readwrite property, but not the setter, so the ivar will still be synthesized for you. Thus, as your code stands, you do not need to explicitly #synthesize.
If you made this property readonly, then implementing a getter would prevent your ivar from being automatically synthesized. Likewise, since this is readwrite, if you implemented both the getter and the setter, that would require you to synthesize the ivar (if you wanted one).

Don't use lazy initialization this way. A Deck is useless without cards and, thus, lazy initialization buys you nothing but an indeterminate consumption of CPU whenever the first call to that getter might be. Fortunately, simply creating a mutable array costs nothing (which is also a reason not to use lazy initialization).
As well, vending a mutable collection breaks encapsulation. A Deck should contain all the logic for determine what set of Cards it contains and in what order. By vending a mutable collection, an external bit of code can change that order behind the Deck's back.
Beyond that, what does it even mean to "set" a Deck's cards? Going that route seemingly pushes all logic related to maintaining the Deck outside of the Deck class, begging the question as to why the deck is nothing more than a plain old array in whatever class uses the deck.

In iOS 7, you don't normally need synthesize. If you want a custom getter, just define one. You'll get the default setter for free.

Related

Why doesn't the managedObjectContext property synthesize its own instance variables ?

appDelegate.h
#property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
I had to do this in appDelegate.m
#synthesize managedObjectContext = _managedObjectContext;
I'm confused because according to apple
Note: The compiler will automatically synthesize an instance variable
in all situations where it’s also synthesizing at least one accessor
method. If you implement both a getter and a setter for a readwrite
property, or a getter for a readonly property, the compiler will
assume that you are taking control over the property implementation
and won’t synthesize an instance variable automatically. If you still
need an instance variable, you’ll need to request that one be
synthesized: #synthesize property = _property;
According to this it should create an instance variable as long as it created at least one accessor method. So does this mean that no accessors methods where created when I declared the property? What is the reason. Please explain.
I'm assuming somehow the compiler knows that NSManagedObjectContext has accessor methods. So it didn't create any and therefor it didn't create instance variables.
You haven't shown the code for the corresponding .m file, but I'm assuming you implemented the managedObjectContext property getter method programmatically. As the documentation says, "The compiler will automatically synthesize an instance variable in all situations where it’s also synthesizing at least one accessor method." But if you provide an implementation of the getter method for a readonly property, the compiler isn't synthesizing any accessor methods.
As the documentation says...If you provide atleast one accessor method for either setter or getter, its like telling the compiler...dont bother synthesizing this variable as I have some custom work to do with the setter/getter. Hence the compiler does not auto generate the _ivar. If you need the _ivar, you have to explicitly specify it and then proceed with your customer getter and setter. Its all about Objective C compiler doing things for you unless you say Don't bother...I know what I am doing.

Difference between declaring an attribute and a #property in objective-c

I know that the #property generates the getters and setters in Objective-c. But I've seen some classes where they declare attributes with their respective #property and some times just the #property with no attributes and seams to work the same way. Whats the difference?
I know that the #property generates the getters and setters in Objective-c.
No you don't. #property declares a property which is a getter and optionally a setter (for read/write properties). The generation of the getter and setter is done by the #synthesize in the implementation (or by you writing the getter and setter).
But I've seen some classes where they declare attributes with their respective #property
Do you mean like this?
#interface Foo : NSObject
{
Bar* anAttribute; // <<=== this is an instance variable
}
#property (retain) Bar* anAttribute;
#end
In the modern Objective-C run time, if you #synthesize the property, you can leave out the instance variable declaration and the compiler will put it in for you. Whether you explicitly declare the instance variable or not is a matter of personal preference.
Just to confuse you a bit, in the very latest compiler, you can omit the #synthesize and the compiler will put it in for you as long as you haven't explicitly created a getter or setter.
Under ios 5.0, there are ten different attributes you can attach to a property declaration: nonatomic, readwrite, readonly, getter=name, setter=name, strong, retain, copy, weak, assign. (strong, weak are new under ios 5.0 and are only meaningful if you use ARC).
nonatomic declares that variable access should not be protected against multithreaded concurrent access. This isn't the default, although 99% of the time it's what you want (since this protection makes your code run slower with no benefit if you're not doing multithreading).
readwrite/readonly should be fairly obvious - readwrite is the default, and if you declare a property readonly, it has no setter.
getter=, setter= control what the getter & setter methods should be called. If you omit them, they'll be called property name and set*property name*, respectively.
The remaining attributes (strong, weak, retain, copy, assign) are hints to the memory manager, and their behavior varies depending on whether you're using ARC or not. If you're not, then the "retain" property tells the setter method to automatically call retain on any object that it gets a reference to. This means that you must also call release in the deallocator.
The "assign" property tells the setter not to call retain - so if the object is released by another object, this pointer could be left dangling.
The "copy" property tells the setter to call retain and also to make a copy of the property - this is useful when you get, say, an NSDictionary and you don't want the caller to pass an instance of NSMutableDictionary and change the contents out from underneath you.
If you're using ARC, you'll normally only set "strong" or "weak". (strong is a synonym for retain, so they can be used interchangeably). "strong" tells ARC to retain the variable for you - "weak" tells it not to. "weak" is useful when you have a potential "retain cycle" where object A refers to object B and object A - if they both retain each other, you have a memory leak, so you'll want to make one of them a weak reference.

public objects and use of property

I'm a bit confused; if an object is declared in the .h file it is considered automatically as "public" right? We use a #property in the .h file, however, to edit them? This is where I don't understand: we use the getter/setter for private objects, so why do we use the #property for objects declared in the .h file and thus considered as "public"?
Second thing, I found this example: I don't understand why we use a #synthesize for primaryKey in this code: http://staging.icodeblog.com/wp-content/uploads/2008/08/9-todom1.png
and why we don't use a #property for the database object?
It is not correct that if an object (ivar) is declared in a .h file, then it is public. It is only if getter/setter methods are provided, otherwise it is not.
Indeed, the #property/#synthesize directives are facilities meant to declare and define default getter/setter methods. So, instead of writing them yourself, you just use the directives.
It is also worth noting that declaring properties you get the possibility of using the dot notation to refer properties of your objects. And also that they clarify a lot, thanks to the retain/assign/copy specifiers, how memory is meant to be managed for that properties. (And, of course, #synthesize will just do that correctly for you).
About your sample, in fact, whether an ivar is associated to a property or not is a design choice. Possibly, you just reconsider the assumption that ivars declared in .h files are public by defaults, and it will become clearer. In other words: primaryKey is public, database is not.
A very nice tutorial can be found here but also do not forget Apple docs.
EDIT:
about your question from the comment section:
it is not necessary that every ivar has a property, nor that it has getter/setter in order to be used inside of that class implementation.
#interface SomeClass : NSObject {
AnotherClass* _anotherClassObj;
AThirdClass* _aThirdClassObj;
}
#property (nonatomic, retain) AnotherClass* anotherClassObj;
#end
So, here you have two ivars; only one has got a #property declaration. In your .m file you may have, e.g.
#implementation SomeClass;
#synthesize anotherClassObj = _anotherClassObj;
- (void)initWithClasses:(AnotherClass*)obj1 and:(AThirdClass*)obj2 {
.....
self.anotherClassObj = obj1;
_aThirdClassObj = obj2;
...
}
....
#end
In this code:
#synthesize will provide implementation for getter/setter for anotherClassObj so you can use syntax: self.anotherClassObj = obj1; that syntax can be used equally from inside and outside the class implementation;
when you have no getter/setter (either auto-generated or custom) you can assign directly to an ivar by using the syntax _aThirdClassObj = obj2;, with the semantics of simple pointer copy; anyway, _aThirdClassObj will not accessible from outside that class;
furthermore, #property ... anotherClassObj notwithstanding, you can still refer _anotherClassObj directly in your .m file, like in _anotherClassObj = xxx, bypassing getter/setter, if you ever need it.
One thing you should have clear is that getter/setter are not only a way to make an ivar "public". They also play an important role in managing the retain count (depending on which specifier you choose among retain/assign/copy in the property declaration). So, in self.anotherClassObj = obj1; above, obj1 is assigned to _anotherClassObj and it is also retained (and if _anotherClassObj was previously pointing to an object, that object will be sent a release). Raw ivar assignment does not provide that kind of facility.
In my opinion, the retain count management feature of properties is far more important than visibility for deciding whether I use a property or not.
Not everything in the header is public, by default ivars (items in the { }) are #protected. The purpose of the #property is data encapsulation. #synthesize or #dynamic is used for declaring the way you want to implement your property and one or the other is necessary to prevent crashes and warnings.
Resources:
Defining Classes #protected, #package, #private, #public reference
Declared Properties #property reference

why to declare some instance variables as properties

Though this is somewhat a very basic question but I have some doubts still left after reading so many documents and questions on stackoverflow.com.
I want to know why to declare some instance variables as properties.
MYViewController.h
#interface MyViewController : UIViewController {
UIButton *btn;
NSString *name;
}
#property (nonatomic, retain) UIButton *btn;
#property (nonatomic, retain) NSString *name;
MyViewController.m
#implementation MyViewController
#synthesize btn;
-(void) viewDidLoad()
{
[btn setTitle:#"Hello" forState:UIControlstaeNormal]; //this is first way where there is no need to declare btn as property
[self.btn setTitle:#"Hello" forState:UIControlstaeNormal]; //this is second way where we do need to decalre btn as property as we are accessing it through self
//Setting value of name
name = #"abc"; //this is first way where there is no need to declare name as property
[self setName:#"abc"; //this is second way where we do need to declare name as property as we are accessing its aetter method through self
}
Now in the above code I wanna know when we can use the getter/setter methods of btn variable without declaring it as property then what is the need to declare it as property and which is the better way to set the value of "name".
Somewhere I read that when you want your instance variables to be accessed my other class objects then you should declare them as instance variables. Is it the only situation where we should declare them as properties.
Basically I am a little confused about in which situations to declare the instance variables as properties.
Please suggest.
Thanks in advance.
In short, you don't have to declare instance variables as properties unless you want to.
You declare a variable as a property in order to auto-generate getter and setter methods. In your property declaration you can specify how you want them set up (retain vs assign, atomic vs nonatomic). Then, the getter and setter are generated with the #synthesize directive.
So, again, there is no right or wrong way to use properties. Some people never use them, some people make every variable a property. It's really up to you.
typically, you'll use them because:
1) the property belongs in the public interface of the class
used when the class needs to expose a given method. the downside is that clients and subclasses may abuse the public interface (all objc methods are public, where visible), unless you're careful to hide these details (which is also a pain at times). sometimes you're forced to go well out of your way in order to achieve the class interface you need (with the proper levels of visibility).
2) you want auto-generated accessors
implementing nonspecialized accessors is tedious, and error prone. it's better to save the time and let the compiler generate them for you.
3) to document behavior
sometimes it's better to write #property (copy) NSString * title; instead of over-documenting the expected result.
4) stricter selector matching with dot-syntax
the compiler performs stricter selector matching. prefer to catch the errors/issues at compilation, if possible.
5) to force the subclasses to use them instead of handling the ivars directly
objc ivars are protected by default. you'll often want them to be private (depending on how the class is used and distributed, or just to ensure the subclass uses the base class correctly).
there are a ton of reasons for this. threading and maintenance are the big ones.
if you declare the ivar as private and provide a property for the subclass to use, then the subclass is forced to use the property in their implementation (although there are ways they could cheat) rather than giving them direct access to the ivar.
so... it ultimately depends on your preference, and the implementation details of your class, paired with the interfaces you're using. i don't think there's a hard and fast rule here - lesser evils and convenience are key motivations.

Difference between accessing property methods and class fields (Objective-C)

Assume that I have this piece of code:
#interface Foo : NSObject {
Bar *bar;
}
#property (retain, nonatomic) Bar *bar;
#end
When using this field/property, is there any difference between lines:
[self.bar doStuff];
and
[bar doStuff];
?
When doing assignment, property method will perform correct retaining, but what about the read access to the property, as described above? Is there any difference?
There is a big difference.
[self.bar doStuff] is equivalent to [[self bar] doStuff]
[bar doStuff] is equivalent to [self->bar doStuff]
The former uses the accessor method, the latter just accesses the instance variable bar directly.
If you use the #synthesize directive on your bar property, the compiler will generate two methods for you:
- (void)setBar:(Bar*)b;
- (Bar*)bar;
Also note, that the compiler generated setter method is retaining your Bar instance as you told it in the #property declaration.
Using the accessor self.bar is translated into a method call: [self bar]. The period syntax is just for looks. Accessing the member variable directly doesn't involve an extra function call, and is therefore slightly faster. It really only matters if you're accessing it within a loop, or in some process where that difference will add up. (On the iPhone) The setters created for properties also have some extra overhead for doing key value coding. A KVO notification is sent when you call "setBar:" or say "self.bar =" , so calling it over and over will result in a flood of notifications.
Jim is right, though - there's no functional difference between a nonatomic #property and a direct use of the variable in your code. Unless you're really concerned with the speed, using the property is probably your best bet.
A synthesized (or correctly hand-written) nonatomic accessor will be functionally equivalent to
- (Bar *)bar
{
return bar;
}
so there is no functional difference between your two examples.
However, outside of -dealloc or your initializers, consistently accessing the property via its accessor is a good idea.
If you assign value to your field with a convenient constructor of a Bar class, your Bar field will become a Zombie sooner than your Bar Property with Retain option, because reference count is not incremented by assigning to fields, and sometimes you run into "accessing deallocated objects" error.