obj c: accessor: self vs myInstance - objective-c

In Apple's The Objective-C Programming Language p. 18, they make a distinction between setting a variable with self versus instance reference. e.g
myInstance.value =10;
self.value =10;
1. Would these two set different properties named value?
2. How could self work if there are several instances with properties named value?
They also assert, "If you do not use self., you access the instance variable directly." This would mean that the accessor would not be called if you use
myInstance.value =10;
and KVO wouldn't work. Is this true?
3. Using #Property and #Synthesize (with garbage collection), what is the proper way to set properties of different instances? And what good is the self reference?
A numeric example would help me, please.

1 - Would these two set different properties named value?
No, I think you misunderstand what the guide is saying when it makes a distinction between self.value and myInstance.value. In both cases the setter function (i.e., setValue:) is called.
You use self to access your own properties (that is, referencing properties from within functions in a class that you wrote). Like:
#interface MyObject : NSObject
#property( nonatomic ) NSInteger value;
- (void) doSomething;
#end
#implementation MyObject
#synthesize value;
- (void) doSomething
{
self.value = 10;
}
#end
Whereas you'd use myInstance to set a property in some other variable, from outside that class.
MyObject* anObject = [[MyObject alloc] init];
anObject.value = 10;
2 - How could self work if there are several instances with properties named value?
It wouldn't. See above.
They also assert, "If you do not use self., you access the instance variable directly." This would mean that the accessor would not be called if you use myInstance.value =10; and KVO wouldn't work. Is this true?
No. self.value and myInstance.value both call their accessors (setValue: in this case), and KVO will work. What that assertion means is that if you access an ivar from within your own class, not using the accessor, KVO will not work.
#interface MyObject : NSObject
#property( nonatomic ) NSInteger value;
- (void) doSomething;
#end
#implementation MyObject
#synthesize value;
- (void) doSomething
{
self.value = 10; // This invokes the accessor, and KVO works.
value = 10; // This just sets the instance variable, and KVO won't work.
}
#end
Using #Property and #Synthesize (with garbage collection), what is the proper way to set properties of different instances? And what good is the self reference? A numeric example would help me, please.
Just as shown above, use the instance name. self is only used for accessing properties within a class. Examples above.

The best way to under stand self is to think of how it is implemented, as a hidden argument with every method call so the method -[UIView drawRect:] has a c function implementation like
BOOL drawRect:( UIView * self, SEL _cmd, NSRect r ) { }; // of cause : is not legal in c
and calling the method is a little like (ignoring the dynamic look up)
UIView * v = ...
NSRect r = ...
drawRect:( v, #selector(drawRect:), r );
so if you invoke a property in the drawRect: implementation you are doing it for the hidden object parameter called self.
Accessing the instance variable directly will stop KVO from working, but sometimes you want that, for example when initialising them perhaps.
IF you mean automatic reference counting when you say Garbage Collection, most of the time for objects you want them to be strong or copy, immutable strings using copy will be turned into a retain and if it is mutable then you often want a copy to protect against the original being changed underneath you.
One potential issue with strong is that you can end up with circular references where if you follow the links around you comeback to the original object so each object is indirectly retaining itself and you have a catch-22 situation where the object has to release itself before it can release itself. So in these situations you need to use weak. You can usually workout who should retain and who should weak by think about which object conceptually owns the other.
For non-object you have to use assign.

self.property and [self method]; are strictly used within a class to refer to itself. You do not ever refer to the object within itself with anything but self.
On the contrary, use instances of an object to refer to an object from another class. For instance, I would refer to a UIImageView from my viewController in a way like:
UIImageView* imgView = [[UIImageView alloc] init];
[imgView setFrame:CGRectMake(0,0,320,480)];
But if I were editing a subclass of UIImageView that I called, say rotatingImageView:
#implementation rotatingImageView
-(id)init
{
//Super instantiation code that I don't remember at the moment goes here
[self setFrame:CGRectMake(0,0,320,480)];
}
This is just an example of a method.
Once again, you use self strictly within its own class, and you use other variables to reference an instance of another class.
Hope that makes sense.

My big problem was how an ivar and a property could be tied together when they have different names, especially with multiple ivars.
I finally found that if name of property doesn't match name of ivar, a new ivar is synthesized. This is accessed by self.propertyname (within object) or object.propertyname (outside of object), not the declared ivar.
To tie disparate names of ivar and property, equate them as in
#synthesize propertyname = ivarname.
Thanks to
http://blog.ablepear.com/2010/05/objective-c-tuesdays-synthesizing.html

Related

Setting default values for inherited property without using accessor

I always see people debating whether or not to use a property's setter in the -init method. My problem is how to create a default value in a subclass for an inherited property. Say we have a class called NSLawyer -- a framework class, that I can't change -- with an interface that looks like this:
#interface NSLawyer : NSObject {
#private
NSUInteger _numberOfClients;
}
#property (nonatomic, assign) NSUInteger numberOfClients;
#end
And an implementation that looks like this:
#implementation NSLawyer
- (instancetype)init
{
self = [super init];
if (self) {
_numberOfClients = 0;
}
return self;
}
#end
Now let's say I want to extend NSLawyer. My subclass will be called SeniorPartner. And since a senior partner should have lots of clients, when SeniorPartner gets initialized, I don't want the instance to start with 0; I want it to have 10. Here's SeniorPartner.m:
#implementation SeniorPartner
- (instancetype)init
{
self = [super init];
if (self) {
// Attempting to set the ivar directly will result in the compiler saying,
// "Instance variable _numberOfClients is private."
// _numberOfClients = 10; <- Can't do this.
// Thus, the only way to set it is with the mutator:
self.numberOfClients = 10;
// Or: [self setNumberOfClients:10];
}
return self;
}
#end
So what's a Objective-C newcomer to do? Well, I mean, there's only one thing I can do, and that's set the property. Unless there's something I'm missing. Any ideas, suggestions, tips, or tricks?
You should do exactly has you have; call the accessor. The declaring class typically avoids calling its own accessors in init to avoid accidentally calling an overridden accessor in a subclass that might rely on the consistency of data you haven't initialized yet. Your superclass on the other hand should be completely consistent by the time the subclass's init is run, so there is no problem using superclass accessors at that time.
Consider the common and general case: you want to set your transform in a UIView subclass. How would you solve that other than call setTransform:? Subclassing non-Apple code is no different.
Make it #protected. It is very rare to make an ivar or property private these days. Private ivars and/or properties are better declared in the implementation. For that matter #protected ivars/properties are rarely seen in Objective-C but perfectly fine.
Using a setter either as a method or with dot notation is just wrong (yes it works but is really bad form), if you want use setters/getters declare a property.

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.

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 -- initializing inherited variables of a subclass object

I have a class MyClass. I am exaggerating here, but let's say MyClass has 1000 instance variables. I then create a subclass called MySubClass with all the instance variables MyClass has, plus one more.
Question: given an object MyObj of class MyClass, is there an easy way to create a corresponding object MyDerivedObj of class MySubClass, such that the instance variables of MyDerivedObj are the same as the instance variables of MyObj? By "the same", I mean strongly the same, in the sense that if an instance variable of MyObj is a pointer to an object, the corresponding instance variable of MyDerivedObj should point to the same memory.
Inherently, every instance of an object will have a different id; a different address and a different allocation point in the heap.
Thus, the instance variables of A and the instance variables of B are always going to be at different locations.
Now, there is no reason why the instance variables of A and B can't be wrapped into a struct that is allocated separately. With that, then A and B could both have an instance variable that is a pointer to a single copy of a structure full of values.
In terms of setting all 1,000 ivars, it depends on what you want to set them too. If 0, then they will be set that way automatically on object instantiation. If you want to bcopy() in a templated set of values, I would suggest that you use a pointer to a structure and do a separate allocation. There is no way to bulk-set an object's instance variables without making assumptions about layout that will eventually bite you.
Do those ivars all have to be separate? If I had a similar problem, my first instinct would be to wrap them up in some sort of collection ivar (NS(Mutable)Array/Dictionary/Set) and then you can have a normal getter/setter on it and just do
myDerivedObj.collection = myObj.collection;
Assuming the collection was a property on MyObj class with "assign" memory management policy, I think this should preserve the memory reference.
(I'm still kind of new to this, so shoot down any flaws/errors in my logic.)
It the ivars are marked as #public or #protected, yes, they will be exactly the same.
I suggest you create a 'copy constructor' style initialiser for the parent class MyClass, and invoke that from the child class MyDerivedClass initialiser.
[MyDerivedClass initByCopying:someMyObject plusSomeNewProperties:stuff] ->
[MyClass initByCopying:someMyObject] ->
[NSObject init] -> // alloc, etc.
Here's some pseudocode:
#interface MyClass : NSObject {
int AA;
// ...
int ZZ;
}
#end
#implementation MyClass
-initByCopying:(MyClass*)other;
{
if (self = [super init])
{
self.AA=other.AA;
//...
self.ZZ=other.ZZ;
}
return self;
}
#end
#interface MyDerivedClass {
int AAA;
}
#end
#implementation MyDerivedClass
-initByCopying:(MyClass*)other withNewValue:(int)newVar;
{
if (self = [super initByCopying:(MyClass*)other])
{
self.AAA = newVar;
}
return self;
}
#end
I suspect that if you have 1000 member items you might want to consider using a property bag or kvc for all but the performance sensitive ones, which will make your initByCopying routine much simpler.
There may be a shortcut to implementing the copy constructor using the copy protocol, but I couldn't see how to make it easier than the example I gave above.