Are private variables in Objective-C strong? - iphone

So searching around Stack Overflow this seems to be how to make private variables in Objective-C:
#interface ClassName()
{
#private
NSArray* private;
}
#property (strong, nonatomic) NSArray* public;
#end
Now this is where I get confused. The property is declared as (strong, nonatomic), but the private variable has nothing of the sort. So how does arc know if it's strong or not?

Instance variables are __strong by default.
From Apple's ARC Transition Guide, regarding variables (presumed to include instance variables):
__strong is the default
and later:
With ARC, instance variables are strong references by default—assigning an object to an instance variable directly does extend the lifetime of the object
This holds until the property is connected to the ivar via #synthesize. At this point, the ownership qualifier of the property takes precedence. However, if you declare a property as anything but strong, and then implement both the setters and getters by hand, you'll have to manually declare the backing ivar's ownership qualifier as well.

In the case of a property, the ownership of the associated instance variable is implied by the ownership of the property:
See http://clang.llvm.org/docs/AutomaticReferenceCounting.html:
If a property is synthesized, then the associated instance variable is
the instance variable which is named, possibly implicitly, by the
#synthesize declaration. If the associated instance variable already
exists, then its ownership qualification must equal the ownership of
the property; otherwise, the instance variable is created with that
ownership qualification.
Generally, Objective-C objects are by default strong:
If an object is declared with retainable object owner type, but
without an explicit ownership qualifier, its type is implicitly
adjusted to have __strong qualification.
Note that since the LLVM 4.0 compiler (Xcode 4.4), the #synthesize statement and the associated instance variable is created automatically, so you need only to declare the property.

The qualifiers on #property specify the behavior of the synthesized setter and other ARC inserted code. Variables themselves aren't really strong or not, they're just memory locations. So you've got it coded strong right now.
The way to make it private (and strong) is to declare it strong in a category inside .m file.
// .h
// nothing
// .m
#interface ClassName()
#property (strong, nonatomic) NSArray* myStrongPrivateProperty;
#end
// that's it

Related

In Objective-C, when should I use property and when should I use instance variable?

I'm not familiar with the program language which has both property and instance variable.
So I don't know good ways to use property and instance variable.
Now I use only properties in my Objective-C code and I don't use any instance variables.
Do I need to use instance variable?
Or using only property is the best practice for Objective-C?
#interface ViewController : UIViewController
{
// instance variable
#public
int a;
}
// property
#property(nonatomic, strong) NSString *b;
#end
The basic difference between variable and property is that, you can give attributes to property. You can not give any attributes to variable.
So, if you wish to have any specific behavior like retaining the variable, accessing it atomically, have access out side the class, you should go for the properties.
If you simply want to access the variable with in the class and no special behavior is attached to that variable, no need to access it via property. You can directly use variable itself. It will improve the performance also.
There are some advantages a #property has over an ivar:
Memory management : Behind the scenes it will create a setter which creates the variable with correct memory management. It will save you some headaches because you can easily see how the memory management is done (strong/weak and retain/copy/assign).
Accessibility from other classes: if you declare your #property in the .h and #synthesize it in the .m you ivar will be public readable and writeable. You can prevent this with a privat class extension. You even can declare a #property public readonly and declare them internally readwrite via a privat class extension.
Eg: a private property
// [In the implementation file]
#interface MyClass ()
#property (nonatomic, retain) NSMutableArray* someData; // private!!
#end
#implementation MyClass #synthesize someData
#end
Custom getter and setter: If you like you can still write custom getter and setters and you can even just write a getter or setter and let the other one automatically #synthesize. And you can write custom logic into such a getter and setter e.g. you can reload a tableview after a #property has changed.
Automatic Key-Value-Observing (KVO) compliant: If you use or planning to use KVO you get it basically for free by just declaring the property. Nothing else need to be done!
Dot notation: You can access getter and setter via dot notation if you have the #property.
self.myIvar = (id) someThing;
[array addObject:self.myIvar];
If you need you iVar to be public it is simpler to write one #property than writing a getter and setter for a iVar
With a #property you do not need to declare in iVar (in iOS and 64bit Mac Os X applications). You can do it via the #synthesize:
#synthesize myiVar = _myIvar;
Use properties everywhere. Don't even declare instance variables, but synthesize them like this: #synthesize myProperty = _myProperty in order to differentiate them from property names. Properties are good way to cope with memory management as well. The only place you must use the synthesized instance variable is in the dealloc method.
The advantages of the properties are a lot:
- The accessor methods define how will you get and set the value of your instance variable.
- You can customize the accessor methods (for example to lazy instantiate an ivar or do something when a setting a new value like setNeedsDisplay.
- You don't cope with memory management when setting a new value - the setter takes care for releasing/retaining (depending how have you declared the property - retain/copy/assign/strong.
- Some multithreading stuff with the atomic/nonatomic attributes
- You can take advantage of the KVO, when using properties
- And least, but not last - don't worry about performance issues if you have concernes that every time a getter or a setter is called...
A #property is an instance variable that has had some semantic sugar applied to it, to help expose it to the outside world (usually), and to help avoid writing boilerplate code for getting and setting it.
though properties are made generally when you need to access some variable outside of the class, mean getter n setter, but in objective C, an additional need to make property is that the memory management goes on compiler ends, so if you are using some object, not primitive data types, then you should use property and synthesize it, and then release in dealloc if you are using manual reference counting. but again the main objective to make properties it to access some iVar outside the class like passing parameters from one class to other etc.
If you #synthesize a #property, you will have access to a get and a set method, which are very convenient. You can also define how the setter will behave (retain, assign, copy) if it's nonatomic or atomic and if it's read only. If you don't specify anything (aka you don't synthesize the property) the ivar won't be visible outside of the class by default, but you can achieve this by using #public. Logically you can also define them as #private or #protected .
Normally I #synthesize a #property because I want to have access to the ivar from the outside of the class and also because I want a getter and setter methods.
The general opinion is that you should use properties whenever possible. If you're still in doubt, here is Apple's recommendation:
In general, you should use accessor methods or dot syntax for property access even if you’re accessing an object’s properties from within its own implementation, in which case you should use self.
...
The exception to this rule is when writing initialization, deallocation or custom accessor methods
...
You should always access the instance variables directly from within an initialization method because at the time a property is set, the rest of the object may not yet be completely initialized
Read the whole document here for a better understanding of the subject.
As for performance issues, for most apps the gain is insignificant. Read this for a very detailed description.

objective-c interface - declaring variable vs just property?

In Obj-c when declaring a variable within #interface
#interface: NSObject{
MyObject* myObject}
#property (unsafe, nonatomic) MyObject* myObject;
Vs. Only declare it as a property
#interface: NSObject{}
#property (unsafe, nonatomic) MyObject* myObject;
#end
Not declare any var here?
Regards
Christian
#property defines an interface, not an implementation. In your case, you're defining a readwrite property. This means that you're promising to implement -myObject and -setMyObject:. This has nothing to do with ivars.
Now, the most common way to implement those methods is by having them be backed by an ivar. As a convenience, ObjC lets you automatically generate the required methods with an ivar store using #synthesize myObject=myObject_; This says "create the required methods for the property myObject using an automatically created ivar called myObject_." The ivar myObject_ is a real ivar, and you can access it normally (though you generally shouldn't; you should use accessors).
Instead of using #synthesize, you could just implement -myObject and -setMyObject:. You could even use #dynamic myObject; to tell the compiler "don't worry about the implementations for this property; it'll be handled correctly at runtime."
There are a few differences between #property and just declaring methods, but in principle, this line:
#property (nonatomic, readwrite, strong) MyObject* myObject;
is conceptually the same as this:
- (MyObject *)myObject;
- (void)setMyObject:(MyObject *)anObject;
Declaring the ivar yourself has no real impact here. You still need to implement the methods somehow. If your named ivar is the same as the ivar #synthesize is using, then #synthesize just won't create a new ivar.
As a matter of practice, I discourage people from declaring ivars anymore. I recommend just using public and private properties with #synthesize to create any needed ivars. If you must have a manual ivar for some reason, then I recommend declaring them in the #implementation block rather than the #interface.
Skipping declaring the ivar is perfectly fine--but you will not be able to see the ivar's value in the Xcode IDE. One day Apple may fix this.
You will be able to "po" the ivar to inspect it in GDB or lldb.

Basic objective C variable declaration

I am puzzled by how is variable declared in objective C.
1: I see #property and #synthesize statement being used. My question regarding that is, what are these 2 statement for? Why are they always used together? I guess #synthesize is a shortcut to create the getter and setter?
2:Say, I want to declare an NSMutableArray that would be only be accessible inside the class that was declared in. I have to perform myArray = [[NSMutableArray alloc] init] before using the addObject method to write something to it. When do I release the array then?
3:Is there a different way to declaring a variable that is only accessible only at the class it was declared to being accessible at all classes?
4:Similar to question 2, but now the variable is an NSString. Why I don't have to alloc & init it to share the same variable within its own class? Whats the different between self.myString = #""; to myString = #"";
Thanks a lot.
For your first question:
#property (nonatomic, retain) NSString * someProperty;
This declares a property of the class. It becomes part of the public contract of the class but still lacks something important - actual implementation
#synthesize someProperty;
This is compiler sugar, its creates a getter and setter method for your property. To wit, this is the implementation that is needed in order to actually use your property in your class and from other classes.
You will in almost all situations, always have a #synthesize for each #property you declare.
For your second question:
You are correct about how to initialize your array property. In order to release it you would do the following in your classes dealloc method:
- (void) dealloc {
self.myarray = nil;
[super dealloc];
}
This effectively releases the array (assuming you declared your property with the keyword retain).
And for your last question:
Properties of a class are always available from other classes. In order to create a globally accessible variable you would declare it as static.
Ad 1: a property is a construct to control access an ivar (usually private) by getters and setters. Actually, a property doesn't even have to have a supporting ivar. Yes, #synthesize generates getter and setter (and ivar).
Ad 2: You release it when you don't need it anymore. When that is depends on the logic of your code.
Ad 3: If I understand that correcttly, you want #private ivars. Normally, ivars are protected, i.e. only accessible inside the class or in derived classes. Private ivars are only accessible inside the class itself. Properties are publicly accessible.
Ad 4: myString = #"" writes to the ivar directly, while self.myString = #"" uses the property setter.
You need to get a text on Objective-C or find an online tutorial -- it's a sufficiently arcane language that you can't hope to pick it up in dribs and drabs.
There are variables and there are properties -- two different things that intersect somewhat.
You can declare plain old instance variables the same way as in C/C++, more or less:
NSArray* myArray;
eg, placed in the {} enclosed section of the #interface.
But you can also have a PROPERTY, which you declare by saying #property in the #interface declaration (after the closing }). A property has a getter method -- by default called myProperty -- and a putter method -- by default called setMyProperty. If myProperty is the same name as one of your instance variables then you can use #synthesize to automatically create these methods.
Note that properties may be automatically retained when the default setter method is used. This is fairly convenient in terms of managing storage.
But managing storage is a big topic, one that you MUST read some good tutorial on -- we can't explain it in a few paragraphs.
1) #property declares a publicly accessible variable and associated getter and setter. #synthesize causes the compiler to automatically generate the definition (code) of the getter and setter.
2) You would declare the NSMutableArray in your class declaration, in the header file. You would initialize the variable in your init method, and you would release the variable in your dealloc method.
3) The variables created using #property are public. The variables defined in your class declaration (using #interface in the header file) can be declared as private to that class, using the #private keyword.
John, these questions are pretty basic. You would probably get a lot out of the Objective-C Programming Intro here ( http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjectiveC/Introduction/introObjectiveC.html#//apple_ref/doc/uid/TP30001163 ).

what is the difference between a readwrite property and a nonatomic assign property?

I have seen readwrite on int, BOOL etc same as nonatomic, assign.
I am some what confused on this. I do know that on non native objects, we typically do nonatomic, retain.
Here's the short answer:
atomic vs nonatomic primarily ensures that complete values are returned from synthesized getters and that complete values are written by synthesized setters (atomic is default.)
readwrite vs readonly determines whether a synthesized property has a synthesized accessor or not (readwrite has a setter and is the default, readonly does not).
assign vs retain vs copy determines how the synthesized accessors interact with the Objective-C memory management scheme:
assign is the default and simply performs a variable assignment
retain specifies the new value should be sent -retain on assignment and the old value sent -release
copy specifies the new value should be sent -copy on assignment and the old value sent -release.
After reading so many Articles, SO posts and made demo apps to check Variable property attributes, I decided to put all the attributes information together
atomic //default
nonatomic
strong=retain //default
weak= unsafe_unretained
retain
assign //default
unsafe_unretained
copy
readonly
readwrite //default
so below is the detailed article link where you can find above mentioned all attributes, that will defiantly help you.
Many thanks to all the people who give best answers here!!
Variable property attributes or Modifiers in iOS
retain = strong
it is retained, old value is released and it is assigned
retain specifies the new value should be sent -retain on assignment and the old value sent -release
retain is the same as strong.
apple says if you write retain it will auto converted/work like strong only.
methods like "alloc" include an implicit "retain"
Example:
#property (nonatomic, retain) NSString *name;
#synthesize name;
assign
assign is the default and simply performs a variable assignment
assign is a property attribute that tells the compiler how to synthesize the property's setter implementation
I would use assign for C primitive properties and weak for weak references to Objective-C objects.
Example:
#property (nonatomic, assign) NSString *address;
#synthesize address;
readonly
declaring your property as readonly you tell compiler to not generate setter method automatically.
Indicates that the property is read-only.
If you specify readonly, only a getter method is required in the #implementation block. If you use the #synthesize directive in
the #implementation block, only the getter method is synthesized. Moreover, if you attempt to assign a value using the dot syntax,
you get a compiler error.
Example:
#property (nonatomic, readonly) NSString *name;
#synthesize name;
readwrite
setter and getter generated.
Indicates that the property should be treated as read/write.
This attribute is the default.
Both a getter and setter method are required in the #implementation block. If you use the #synthesize directive in the implementation
block, the getter and setter methods are synthesized.
Example:
#property (nonatomic, readwrite) NSString *name;
#synthesize name;
readwrite means that both a getter and a setter exist; the opposite is readonly. Normally the only time you'd explicitly declare a property readwrite is in a class extension for a class where the public interface declares the property readonly — so that it's publicly read-only, but internally you can both get and set.

Can someone explain every word of this Objective-C property declaration?

I'm not familiar with Objective-C syntax, so could someone explain what every term means in the following line of code?
#property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
#property - is a objective-c syntax for declaring and optionally synthesizing accessor methods for instance variable. Read official reference for more details.
nonatomic - means that synthesized getter method will return ivar directly without locking it for thread-safety
retain - means that ivar will be retained in setter method
readonly - the trick to make setter method "private" for class users - so only getter method will be visible for compiler. Usually in implementation file this property is redeclared without readonly attribute using custom category so that setter method can be used inside class itself.
NSManagedObjectContext* - variable type
managedObjectContext - variable name
Once again - best advice here is to read Properties section in official documentation...
readonly accessor means only the getter method is synthesised. The value is read only.
retain accessor means this class retains the pointer, the previous value is released
nonatomic accessor means that no locking is applied to the synthesised getter
#property reveals this member for synthesis so that getters/setters can be created. Without it you would have to access the property directly.
NSManagedObjectContext is a type of object/class, and *managedObjectContext is a pointer to an instance of that object.
Vladimir is correct.
But I will suggest you to read Objective-C 2.0 reference First for long run.