Do properties default to nil? - objective-c

If i don't use an ivar for properties, but do this:
#interface someClass : NSObject
#property (nonatomic, retain) NSArray * someArray;
#end
#implementation someClass
#synthesize someArray = _someArray;
- (void) someMethod
{
if( self.someArray == nil ){
// True on the first call?
}
}
#end
The first time I check self.someArray it returns nil, as does _someArray, but is this guaranteed? I read only that ivars are guaranteed to be nil, and since I don't declare a ivar (_someArray is not an ivar), I am not sure if it will be nil everywhere and every time.

It's always nil. Objective-C initialises all the variables in a class to nil when it is allocated. Synthesised ivars follow the same rules.

Properties are backed by instance variables if they are synthesized automatically -- so yes, by default such properties will return nil.

Yes, all properties, ivars and static variables have always been defined to be initialized to nil. Now with ARC this carries over to __strong stack variables (__strong being the default for all object pointers).

Related

What is default variable access rights type in Objective-C?

For example, I have some class A. And then I inherit another class from A.
#interface A : NSObject
{
int _nonHiddenProp;
#private
int _hiddenProp;
}
#property (nonatomic, assign) int property;
#property (nonatomic, assign) int nonHiddenProp;
#property (nonatomic, assign) int hiddenProp;
#end
#implementation A
- (id)init
{
if (self = [super init])
{
_property = 1000;
}
return self;
}
#end
#interface B : A
#end
#implementation TestCapabilitiesChild
- (id)init
{
if (self = [super init])
{
_nonHiddenProp = 1000;
//I cannot call _property and _hiddenProperty
}
return self;
}
#end
But:
A *a = [[[A alloc] init] autorelease];
B *b = [[[B alloc] init] autorelease];
NSLog(#"BClassProperties %d %d %d", b.nonHiddenProp, b.property, b.hiddenProp);
Shows: BClassProperties 1000 1000 0
Why? If I cannot call variable _property in init of B it still is 1000?
You have explicitly declared two instance variables _nonHiddenProp and _hiddenProp of which _nonHiddenProp has visibility to subclasses and _hiddenProp has visibility only to the class it is in. You have also declared three properties: property, nonHiddenProp and hiddenProp.
The first thing to note is that properties are not variables. Properties and instance variables are different things. A property is actually a pair of accessor methods, one to get its value and the other to set its value (the setter may be omitted for read only properties). Note that by "its value" I mean the property's value not the value of any particular instance variable. I might have mentioned this before but properties and instance variables are not the same thing.
As properties are really a pair of methods, the visibility rules for a property are the same as for methods, namely "all methods are public", therefore all properties are also public.
If you do not provide implementations for the property's two accessors and you do not explicitly synthesise the property, the compiler will automatically provide implementations. This it does by:
first inventing an instance variable name which is the same as the property name but with an underscore in front.
if the instance variable doesn't already exist, it declares one with private visibility.
create getter and setter to get/set the instance variable when the property is got/set.
You can't set the instance variable _property from within the subclass because the subclass does not have visibility of the instance variable. The NSLog works because it is using the property, not the instance variable.
You declared a property for the instance variable... this means, that a setter and getter was syntesized, which are methods... in Objective-C all methods are public (althrough you can "hide" them, or the compiler / IDE may prevent you from compiling)
But in reality and during runtime nothing prevents you from sending a message (calling a method) on that class

Objective-C memory management and nil?

In my book a *joystick that was assigned #property (nonatomic, retain), and it wasn't released only set to nil in the -dealloc method. In the -init method, the same joystick was set to nil. What does this mean?
If you have a property like:
#property (nonatomic, retain)
the setter method generated by synthesize will take care of releasing the object currently pointed to by the ivar before assigning the new one to it. So,
self.property = xxx;
is equivalent (if you like) to:
if (property != xxx) {
[xxx retain];
[property release];
property = xxx;
}
Now, it is considered good practice to set an ivar to nil after releasing it:
[property release];
property = nil;
This is a common release idiom in ObjC.
As you see, if you assign nil to a property (i.e., xxx = nil in the example above) what you get is just this: the ivar will be released and its value set to nil. Assigning nil to a property is therefore just a shorthand for this "release idiom".
Properties are essentially automaticaly generated accessor method to you ivars, you can even override properties, so if you property is call joystick then the automatically generate method is equallent to
- (void)setJoystick:(MyType *)aValue
{
if( aValue != joystick )
{
[joystick release];
joystick = [aValue retain];
}
}
more than this actually happens if you do not have nonatomic, and there maybe stuff to deal with thread access.
Sp you can see that if you set self.joystick you are calling setJoystick: with nil and so release the current value and setting the ivar to nil

Objective-c setter/getter callback

I have an interface with properties.
I would like to know the way to declare callback to reach its instance's setter or getter.
Is there a way to do it?
Sorry for my english and thx for your answers and time.
If you declared a #property for your instance variable, and then synthesized it in your implementation file, your getter and setter are automatically created for you. Example for a NSMutableArray
#interface ...
{
NSMutableArray *array;
}
#property (nonatomic, retain) NSMutableArray *array;
Then on your implementation:
#implementation ...
#synthesize array;
Once that's done, you can get and set your instance variable values by using:
Getter: self.array OR [self array]
Setter: self.array = ... OR [self setArray:...]
I am not sure if I understand your question correctly but if you are trying to get some code executed every time the setter or getter is invoked there are basically two ways to do that:
1) you can overwrite the synthesized getter and/or setter like this
Header:
#interface ...
{
NSString *example;
}
#property (nonatomic, copy) NSString *example;
Implementation:
#implementation ...
#synthesize aString
-(void)setExample:(NSString *)newExample
{
if (example != newExample)
{
[example autorelease];
example = [newExample copy];
// YOUR CODE HERE
}
}
...and similarly for the getter.
2) you can observe the variable via KVO and get a 'callback' whenever the variable changes. This, of course, only runs you code when the setter is invoked, not the getter.

Objective-C Property - Difference Between Retain and Assign

I think I am missing something about property attributes.
First, I can't understand the difference between retain and assign.
If I use assign, does the property increase the retain counter by 1 to the setter and also to the getter, and do I need to use release to both of them?
And how does this work with readwrite or copy? From the view of a retain count.
I am trying to understand when i need to use release after working with a property (setter and getter)
#property (readwrite,assign) int iVar;
What does assign do here?
What is the difference between:
#property (readwrite,assign) int iVar;
and
#property (readwrite,retain) int iVar;
and
#property (readwrite) int iVar;
Many thanks...
what is the different between : #property (readwrite,assign) int iVar; to #property (readwrite,retain) int iVar; to #property (readwrite) int iVar;
The setter for #property (readwrite,assign) sometype aProperty; is semantically equivalent to
-(void) setAProperty: (sometype) newValue
{
ivar = newValue;
}
The above is more or less what you will get if you put
#asynthesize aProperty = ivar;
in your implementation.
The setter for #property (readwrite,retain) sometype aProperty; is semantically equivalent to
-(void) setAProperty: (sometype) newValue
{
[newValue retain];
[ivar release];
ivar = newValue;
}
Clearly, it makes no sense to retain or release an int, so sometype must be either id or SomeObjectiveCClass*
The setter for #property (readwrite,copy) sometype aProperty; is semantically equivalent to
-(void) setAProperty: (sometype) newValue
{
sometype aCopy = [newValue copy];
[ivar release];
ivar = aCopy;
}
In this case, not only must sometype be an objective C class but it must respond to -copyWithZone: (or equivalently, implement NSCopying).
If you omit retain or assign or copy, the default is assign.
By the way, I have simplified the above by not considering the locking that occurs because the properties don't also specify nonatomic.
There are two kind of specifiers:
The readwrite specifier tells that the property will be read/write, so when you do a # synthesize it will create both the getter and the setter.
There's also readonly, to specify that the property will only have a getter.
The other modifiers specify how the properties will behave respect of the reference counting:
The assign modifier, tells that the ivar will simply be assigned with whatever the setter receives. So, in case of an object, retain won't be called.
With retain, whenever you use the synthesized setter, retain will be called, so the object will be retained. This means that the class that has the setter needs to release it at some point (probably in its dealloc method).
As for copy, it means that instead of retain, the object will receive a copy message. This means that you'll end up with a copy of the original object, with a retain count of one, so again, you are responsible of releasing it.

Ok to release a pointer thats nil?

If I create a new object that includes two object pointers (see below) when the object is created the pointers are set to point to nil;
#interface rocketShip : NSObject {
NSString *name;
NSNumber *thrust;
}
If (for some unexpected reason) I don't assign these pointers and later release them in my dealloc method is that ok, I am pretty sure it is, just wanted to check?
- (void)dealloc{
[name release];
name = nil;
[thrust release];
thrust = nil;
[super dealloc];
}
gary
Sending a message to nil won't cause an error, so this is fine. You need to make sure the pointers are actually nil though - sending a message to a garbage pointer will likely cause errors.
Yes, you can do this because you can safely send a message (such as release) to nil and it will just do nothing.
If you use the accessor property to create your get/set methods:
#interface rocketShip : NSObject {
NSString *name;
NSNumber *thrust;
}
#property (retain, nonatomic) NSString *name;
#property (retain, nonatomic) NSNumber *thrust;
And in your .m file:
#synthesize name;
#synthesize thrust;
You can then just set your variable to nil in dealloc. This will in fact call your setter and decrement the reference count by one and clean things up.
It’s important in Objective-C to distinguish between objects and variables. You cannot release a pointer (the value of a variable), you can only release an object (the object to which a pointer refers). A nil pointer refers to no object, so messages sent to nil do nothing (which is generally safe).