Is there a link between an object named "a" and an object named "_a"? - objective-c

I am new to iOS so take me slow. When i declare an object in my .h view controller named "_a" and i declare a property "a" and when i synthesize in the .m file
#synthesize a=_a;
must i use "a" or "_a" when i modify that object ? ( "a" is a UINavigationController in my case).
In another question, does my compiler automatically draw a connection from a object declared "ob" to a "_ob" declaration ?
Again, sorry for the poor explanation but this environment isn't quite something i am use to.

An object declared like this:
#interface Example : NSObject {
NSObject *_a;
}
#property (retain) NSObject *a;
#end
And implemented like this:
#import "Example.h"
#implementation Example
#synthesize a = _a;
#end
Makes an ivar named _a and two accessor methods in the Example object. The accessor methods have these signatures:
- (NSObject *)a;
- (void)setA:(NSObject *)theA;
Method a returns the object in the _a ivar. Method setA releases the object stored in _a (if not nil), assigns the parameter to _a, and sends the parameter an retain message.
These methods may also be access through dot notation:
Example *e = [[Example alloc] init];
// These two are equivalent.
e.a = anotherNSObject;
[e setA:anotherNSObject];
// These two are equivalent.
anotherNSObject = e.a;
anotherNSObject = [e a];
Accessing _a directly will circumvent the accessor methods, potentially causing problems such as memory leaks. For example if _a holds the only reference to an object and a new object reference is assigned to _a the old object will become a leaked object.
To directly answer your two questions:
You may use either a or _a. In most cases you'll be better off using _a when reading the value within methods of the object declaring a, and setA (or a in dot notation) when setting the value of _a. Objects that use Example objects should use the accessor methods (with or without dot notation).
The complier does not automatically make a connection between ob and _ob declarations. In this example the #synthesize a = _a; statement makes the connection with the optional = _a. The ivar may have any name. #synthesize a = george; would also be valid. Without the = _a part the compiler would make an ivar named a and two accessor methods.
One further note: You may omit the declaration of _a in the interface, which restricts the scope of the _a ivar to just the implementation of the Example object. Adding the optional = _a to the #synthesize statement will make as ivar of the same type as the property declared in the interface.

#synthesize tell to compiler to generate setter and getter methods for your property. You can use _a as ivar or self.a as property, there are no difference.
Also you can set your class variable from another class via this property
[myClassInstance setA:newA];
oldA = [myClassInstance a]; //oldA = myClassInstance.a

Related

storing instance reference in singleton in obj-c

Let's say I have 2 classes, A and B. A is a singleton. I declare A in B, so I can access the singletons vars in methods in B.
B then creates an instance of another class, say class C.
C Then creates an instance of another class, say class D.
What I need to do is run a method in the instance of class B, from class D, and that's what is driving me nuts.
My first thought was to put a reference to the instance of class b, in my singleton (class A), something like...
sharedInstance.classBReference = self;
..and then declare the singleton in Class D, and then use something like this in class D instance...
[sharedInstance.classBInstance classBInstanceMethod];
But of course as soon as I did..
classB *classBReference;
In the header of my singleton, it game me the "unknown type" which I read about on here, so instead, I put a
#class classB;
above the #interface, and then I was able to declare...
classB *classBReference;
Without an error of unknown type, but in the init method of class B, this...
sharedInstance.classBReference = self;
Still gives me an error of type
"property classBReference not found on objet of type "class A*" (the singleton) did you mean to access ivar classBReference?"
And I have no idea why it's doing that, what's the solution? or is there a better way to do what I'm trying to do?
Dots and Arrows
The "dot notation" is a somewhat recent addition to Objective-C and provides a shorthand notation for accessors. If you have a pointer to an object (or a struct!), you cannot access its instance variables with . but only with ->.
Your line
sharedInstance.classBReference = self;
is exactly the same as
[sharedInstance setClassBReference:self];
The problem is that you don't have any such method -setClassBReference:. In order to set the instance variable, you must instead write
sharedInstance->classBReference = self;
#protected variables
After switching your line with this one, you may (if you haven't made it #public) see the error
Instance variable 'classBReference' is private
In this case, you need to alter your classA interface so that classBReference is declared to be #public. Your list of instance variables in classA should look something like
#interface classA : NSObject
{
//#protected
//(The #protected keyword is optional when at the beginning of the list; instance
//variables are protected by default, which is why you're needing to declare your
//instance variable classBReference to be #public (since classB is not a subclass
//of classA and consequently cannot access its protected instance variables).
//....
//some protected instance variables
//....
#private
//....
//some private instance variables
//....
#public
//....
//some public instance variables
classB *classBReference;
//....
#protected
//....
//some more protected instance variables
//Note that #protected is not optional in order to make the instance variables
//here be protected since they are declared subsequent to the prior #public.
//....
}
//....
#end
Using #properties
The case of classBReference
That being said, it is widely regarded as a better practice to use accessors rather than instance variables in general. In order to do this, you should add a property to your classA interface:
#interface classA : NSObject
{
classB *classBReference;
}
#property classB *classBReference;
#end
and synthesize the classBReference property to access the classBReference instance variable in classA's implementation as follows:
#implementation classB
#synthesize classBReference = classBReference;
The general set-up
The #synthesize is somewhat unclear on account of the fact that we have both an instance variable and a property with the same name. Some clarification is in order. In general, in a class's ("MyObject" in this example) #interface one declares an instance variable ("myVariable" in this example) and a property ("myProperty" in this example).
#interface MyObject : NSObject
{
SomeObject *myVariable;
}
#property SomeObject *myProperty;
#end
In the class's #implementation one has the line
#synthesize myProperty = myVariable.
The result of this code is that, given an instance
MyObject *object = //...
of the class, one is able to write
SomeObject *someObject = //...
[object setMyProperty:someObject];
and
SomeObject *someOtherObject = [object myProperty];
The result of calling -setMyProperty: on the instance of MyObject is that myVariable is set equal to the argument passed into the method--in this case someObject. Similarly, the result of calling -myProperty on the instance of MyObject is that myVariable is returned.
What does it get us?
Without the #property and #synthesize directives, one would have to declare the methods
- (void)setMyProperty:(SomeObject *)myProperty;
- (SomeObject *)myProperty;
manually and define them manually as well:
- (void)setMyProperty:(SomeObject *)myProperty
{
myVariable = myProperty;
}
- (SomeObject *)myProperty
{
return myVariable;
}
The #property and #synthesize provide some abridgment to this code. The amount of code that is generated for you becomes even more beneficial when you use various of the property attributes.
Note: There is more to say about the #property and #synthesize directives. For a start, not only can you write #synthesize myProperty; omitting the variable name, you can omit the synthesizing of myProperty entirely, and the variable names that are used automatically are different from one another in these two cases.
A Bit More on Dot Notation
The dot notation from your question provides another layer of abbreviation. Rather than having to write
[object setMyProperty:someObject];
you are now able to write
object.myProperty = someObject;
Similarly, rather than having to write
SomeObject *someOtherObject = [object myProperty];
you are now able to write
SomeObject *someOtherObject = object.myProperty;
It is important to note that this is just just notation. Though it "kinda looks like" we're doing simple assignment when we "set object.myProperty equal to someObject", that is not the case. In particular, when we execute the line
object.myProperty = someObject;
the method
- (void)setMyProperty:(SomeObject *)someObject
is executed. For this reason, dot notation is a subject of some contention. It is a convenience, but it is important to keep in mind what your code is doing.
The error message tells you the answer. You should define classBReference as property or use classBReference as ivar.
It sounds like you'd be less confused by avoiding the global variable (aka singleton). Give the C a reference to the B when the B creates the C. Give the D a reference to the B when the C creates the D.
If you need to avoid a retain cycle, make the back-references to the B either weak (if your deployment target is at least iOS 5.0) or unsafe_unretained (if your deployment target is earlier than iOS 5.0).

obj c: accessor: self vs myInstance

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

Property vs. ivar in times of ARC

It is my understanding that setting an ivar now retains the object being assigned to it, since setting variables defaults to the strong qualifier. Because ivars are in the scope of the object they are declared in and strong retains objects within the scope of the variable, this means the ivars value would never be released while the object containing the ivar is still alive.
Is this correct?
If so, am I right in thinking that there is, in terms of memory management, no difference between a retaining (strong) property and a simple ivar anymore?
If a variable:
Is declared in a class using ARC.
Is used solely for class implementation (not exposed as part of the class interface).
Does not require any KVO.
Does not require any custom getter/setter.
Then it is appropriate to declare it as an ivar without a corresponding #property/#synthesize, and to refer to it directly within the implementation. It is inline with Encapsulation to declare this ivar in the class implementation file.
// MyClass.h
#interface MyClass : ParentClass
#end
// MyClass.m
#implementation MyClass {
NSString *myString;
}
- (void)myMethod {
myString = #"I'm setting my ivar directly";
}
#end
This ivar will be treated as __strong by the ARC compiler.
It will be initialized to nil if it is an object, or 0 if it is a primitive.
You can't use KVO and do custom getter and setters with instance variables other than that they are very similar when using ARC.

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.

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.