How do I create a manual lock on an atomic property's ivar in objective-c? - objective-c

I want to expose an atomic property in my obj-c class, but internally I'd prefer to access it's instance var directly rather using self.myproperty for every reference. How do you manually create a lock to block the external read?
So I want...
#property (atomic, strong) NSString *someString;
- myInternalMethodOfClassA
{
...
#synchronized(someString) {
someString = #"New string";
}
...
}
...to block...
- myInstanceMethodInClientClassB
{
ClassA *myobj = [ClassA alloc] init];
...
NSString *str = myobj.someString;
...
}

According to some chat on the Apple Objc-lang list, it's considered a bug to have an atomic property for which you manually create one accessor and synthesize the other. The alternatives are:
Create both accessors yourself and use a bespoke locking object plus #synchronized(anObject), which you can then use elsewhere in your class's code.
#synthesize them and always access them via their accessors (ie self.myAtomicProp internally). This is slower but most likely not a problem in nearly all cases.

Related

with ARC: how to implement a custom atomic property?

In ARC, I want an atomic property for multi-thread access:
#interface MyClass
#property (atomic, strong) NSString *myString;
#end
I also want a custom setter and getter for various reasons, like debugging or tracking.
Solution A, I override the setter and getter:
#implementation MyClass
#synthesize myString = _myString;
static int i;
- (void)setMyString:(NSString *)myString
{
_myString = myString;
NSLog(#"%d", i++);
}
- (NSString *)myString
{
return _myString;
}
#end
Solution B, I extend the class interface to have a different synthesized property:
#interface MyClass ()
#property (atomic, strong) NSString *myPrivateString;
#end
#implementation MyClass
#synthesize myPrivateString = _myPrivateString;
static int i;
- (void)setMyString:(NSString *)myString
{
_myPrivateString = myString;
NSLog(#"%d", i++);
}
- (NSString *)myString
{
return _myPrivateString;
}
#end
Is solution A atomic? Is solution B atomic? If none of them are atomic, should I use objc_setProperty and objc_getProperty, or should I use #synchronized(self), or is there a better locking mechanism to avoid locking self?
(sub-question: in case B, getting or setting _myPrivateString directly is as safe as getting or setting self.myPrivateString or not as safe?)
Is solution A atomic?
No, it's not. As you are providing a custom version of the getter/setter methods, you'll also need to provide the locking mechanism. Using #synchronized(self) will work, however if there is high contention for this property, you might want to create a locking object for each property. That's unlikely, however.
Is solution B atomic?
Yes it is, however be sure to use self.myPrivateString = myString; to ensure you access the getter/setter methods, where the locking is implemented.
I would recommend using solution A as it's simple, which is always good.
Because you are using an instance variable without a leading underscore, you have fallen into the trap of actually accessing the instance variable instead of the accessor method. When you access the instance variable, "atomic" won't do _anything" for you. Anyone with any Objective-C experience will advice you very, very strongly not to use instance variables without the leading underscore. Just remove the #synthesize (so you built yourself a trap, fell into it, and you actually did extra work to do so).
So none of your solutions is in any way atomic.

Which one is initialized, property or its instance variable

Suppose I have a property called myPropertyName defined in my class MyClassName. Manual memory management is used throughout this post.
MyClassName.h
#import <UIKit/UIKit.h>
#interface MyClassName : NSObject {
#private
NSObject* myPropertyName;
#public
}
#property (nonatomic, retain) NSObject* myPropertyName;
// Some methods prototypes are here
#end
MyClassName.m
#import "MyClassName.h"
#implementation MyClassName
#synthesize myPropertyName;
// Some methods are here
#end
I'm confused with usages such as the place of myPropertyName declaration, its difference between instance variable. For example, what is the difference among these three statement of initialization code, for example, in the customized -(void)init method for my class myClassName.
self.myPropertyName = [[[NSObject alloc] init] autorelease];
This one is calling myPropertyName setter, but I'm not sure what is the name of the instance variable being used in the setter, myPropertyName (since I've declared a #private field named myPropertyName) or _myPropertyName (people say that this one with underbar is the default)?
myPropertyName = [[NSObject alloc] init];
Does this initialize the instance variable of the myPropertyName property? If I don't have #synthesize myPropertyName = _myPropertyName;, would it be wrong since the default instance variable for the property is said to be _myPropertyName.
_myPropertyName = [[NSObject alloc] init];
Is _myPropertyName still declared as the instance variable for my property myPropertyName even if I use #synthesize myPropertyName; and #private NSObject* myPropertyName;?
In my understanding, a property is just a name (such as myPropertyName), there should be some instance variable encapsulated to be used in actual operations in the code, such as assigning values.
First off, I highly recommend reading Apple's documentation on properties, also linked by nhgrif. However, I understand docs can be a bit dense reading material (though Apple's, I find, are not so bad), so I'll give a brief overview of properties here.
I like examples, so I'm going to rewrite your two classes in a bit more current form.
MyClassName.h
#import <UIKit/UIKit.h>
#interface MyClassName : NSObject
#property (nonatomic, strong) NSObject *myPropertyName;
// method prototypes here
#end
MyClassName.m
#import "MyClassName.h"
#implementation MyClassName
// some methods here
#end
The class MyClassName now has a property called myPropertyName of type NSObject *. The compiler will do a lot of work for you for "free" in this instance. Specifically, it will generate a backing variable, and also generate a setter and getter for myPropertyName. If I were to rewrite the two files, and pretend I'm the compiler, including that stuff, they would look like this:
MyClassName.h
#import <UIKit/UIKit.h>
#interface MyClassName : NSObject {
NSObject *_myPropertyName;
}
#property (nonatomic, strong) NSObject *myPropertyName;
- (void)setMyPropertyName:(NSObject *)obj;
- (NSObject *)myPropertyName;
#end
MyClassName.m
#import "MyClassName.h"
#implementation MyClassName
- (void)setMyPropertyName:(NSObject *)obj
{
_myPropertyName = obj;
}
- (NSObject *)myPropertyName
{
return _myPropertyName;
}
#end
Again, all of this is happening for "free": I'm just showing you what's happening under the hood. Now for your numbered questions.
self.myPropertyName = [[[NSObject alloc] init] autorelease];
First of all, you should probably be using Automatic Reference Counting, or ARC. If you are, you won't be allowed to call autorelease. Ignoring that part, this works fine. Excluding the autorelease, this is exactly equivalent to:
[self setMyPropertyName:[[NSObject alloc] init]];
Which, if you look at the second .m file I wrote out, above, will basically translate to:
`_myPropertyName = [[NSObject alloc] init];
myPropertyName = [[NSObject alloc] init];
As written, this code will give a compiler error, since there is no variable called myPropertyName in this class. If you really want to access the instance variable underlying (or, "backing") the myPropertyName property, you can, by using its real name:
_myPropertyName = [[NSObject alloc] init]; // note the underscore
But most of the time, it's better to use the setter, as in point 1., since that allows for side effects, and for Key-Value Coding, and other good stuff.
_myPropertyName = [[NSObject alloc] init];
Oh. Well you got it. See point 2.
You mentioned that:
I'm confused with usages such as the place of myPropertyName declaration, its difference between instance variable. For example, what is the difference among these three statement of initialization code, for example, in the customized -(void)init method for my class myClassName.
In case it hasn't been made clear, a property is something of an abstract concept; its data is stored in a normal instance variable, typically assigned by the compiler. Its access should usually be restricted to the setter and getter, with important exceptions. To keep this answer short, I won't go into more detail than that.
One more thing: as nhgrif mentioned, you don't need to use the #synthesize keyword anymore. That is implicitly understood by the compiler now.
If you're not sure about any of this, post a comment or, better yet, read the docs.
Let's take this example:
#property NSString *fullName;
If in the implementation, we override the setters and getters, and in these setters and getters, we don't use an instance variable fullName, it is never created. For example:
- (NSString *)fullName
{
return [NSString stringWithFormat:#"%# %#", self.firstName, self.lastName];
}
- (void)setFullName:(NSString *)fullName
{
//logic to split fullName into two strings
//self.firstName = etc
//self.lastName = etc.
}
In this example, there is no instance variable for fullName created.
This is according to Apple's Official Documentation
If, however, you don't override both the setter and getter, an instance variable is created.
As a sidenote, you can declare a property readonly, and then simply overriding the getter (without using the variable) will prevent an ivar being created. Likewise, you can declare a property writeonly and just override the setter.

Initializers and copy

I've just been reading a short blog post from Craig Hockenberry about ARC and copy. The question I now have is should parameters passed to initializers that are assigned to instance variables always use copy? Or does it depend on the type of the instance variable?
#import "MyObject.h"
#implementation MyObject {
SomeType *_ivar1;
SomeOtherType *_ivar2;
}
-(id)initWithParam1:(SomeType *)param1 andParam2:(SomeOtherType *)param2
{
if ((self == [super init])) {
_ivar1 = [param1 copy]; // Always good
_ivar2 = [param2 copy]; // practice?
}
return self;
}
#end
I think the key to understanding the post is in this statement:
Since I think it’s a bad idea to use accessors during -init the copy semantics defined by the #property are never used and ARC happily retains the reference instead of copying it.
I think that Craig is talking specifically about the following case:
#interface MyObject : NSObject {
SomeType *_ivar1;
}
-(id)initWithParam1:(SomeType *)param1;
#property (copy, nonatomic) SomeType* prop1;
#end
#implementation MyObject
#synthesize prop1 = _ivar1;
-(id)initWithParam1:(SomeType *)param1 {
if ((self == [super init])) {
/*
Craig could have called
self.prop1 = param1;
but he believes that it's a bad idea to call accessors
from the initializer, so he calls copy explicitly.
*/
_ivar1 = [param1 copy];
}
return self;
}
#end
Depends on the type of the variable and intent.
For simple types -- NSString, NSArray, NSNumber, etc... -- you use copy because you generally want the stored type to be immutable. I.e. it doesn't make sense to have a firstName property where something externally can modify it by passing in an instance of NSMutableString.
For more complex classes -- ones that encapsulate both state and functionality -- you generally do not want to copy it exactly because that state may be changing over time. For example, if your app were a streaming video app that had a VideoPlayer instance that played a video encapsulated in a StreamingVideo instance, you wouldn't want to copy the StreamingVideo as its internal state is constantly going to be changing as more data is downloaded (or an error occurs).
I.e. copy is used when you want an immutable snapshot of state and a reference is used when you want object A to be connected to B for purposes of changing/monitoring/querying B's state.
And, yes, you want it to be consistent. If a property is copy and you have a convenience initializer that sets that property, make sure the convenience initializer also copies whatever is set to the property.

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.

Is there a difference between an "instance variable" and a "property" in Objective-c?

Is there a difference between an "instance variable" and a "property" in Objective-c?
I'm not very sure about this. I think that an "property" is an instance variable that has accessor methods, but I might think wrong.
A property is a more abstract concept. An instance variable is literally just a storage slot, like a slot in a struct. Normally other objects are never supposed to access them directly. A property, on the other hand, is an attribute of your object that can be accessed (it sounds vague and it's supposed to). Usually a property will return or set an instance variable, but it could use data from several or none at all. For example:
#interface Person : NSObject {
NSString *name;
}
#property(copy) NSString *name;
#property(copy) NSString *firstName;
#property(copy) NSString *lastName;
#end
#implementation Person
#synthesize name;
- (NSString *)firstName {
[[name componentsSeparatedByString:#" "] objectAtIndex:0];
}
- (NSString *)lastName {
[[name componentsSeparatedByString:#" "] lastObject];
}
- (NSString *)setFirstName:(NSString *)newName {
NSArray *nameArray = [name componentsSeparatedByString:#" "];
NSArray *newNameArray [[NSArray arrayWithObjects:newName, nil] arrayByAddingObjectsFromArray:[nameArray subarrayWithRange:NSMakeRange(1, [nameArray size]-1)]];
self.name = [newNameArray componentsJoinedByString:#" "];
}
- (NSString *)setLastName:(NSString *)newName {
NSArray *nameArray = [name componentsSeparatedByString:#" "];
NSArray *newNameArray [[nameArray subarrayWithRange:NSMakeRange(0, [nameArray size]-2)] arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:newName, nil]];
self.name = [newNameArray componentsJoinedByString:#" "];
}
#end
(Note: The above code is buggy in that it assumes the name already exists and has at least two components (e.g. "Bill Gates" rather than just "Gates"). I felt that fixing those assumptions would make the actual point of the code less clear, so I'm just pointing it out here so nobody innocently repeats those mistakes.)
A property is a friendly way of implementing a getter/setter for some value, with additional useful features and syntax. A property can be backed by an instance variable, but you can also define the getter/setter to do something a bit more dynamic, e.g. you might define a lowerCase property on a string which dynamically creates the result rather than returning the value of some member variable.
Here's an example:
// === In your .h ===
#interface MyObject {
NSString *propertyName;
}
// ...
#property (nonatomic, retain) NSString *propertyName;
// === In your .m #implementation ===
#synthesize propertyName /* = otherVarName */;
The #property line defines a property called propertyName of type NSString *. This can be get/set using the following syntax:
myObject.propertyName = #"Hello World!";
NSLog("Value: %#", myObject.propertyName);
When you assign to or read from myObject.propertyName you are really calling setter/getter methods on the object.
The #synthesize line tells the compiler to generate these getter/setters for you, using the member variable with the same name of the property to store the value (or otherVarName if you use the syntax in comments).
Along with #synthesize you can still override one of the getter/setters by defining your own. The naming convention for these methods is setPropertyName: for the setter and propertyName (or getPropertyName, not standard) for the getter. The other will still be generated for you.
In your #property line you can define a number of attributes in parens for the property that can automate things like thread-safety and memory management. By default a property is atomic meaning the compiler will wrap #synthesized get/set calls with appropriate locks to prevent concurrency issues. You can specify the nonatomic attribute to disable this (for example on the iPhone you want to default most properties to nonatomic).
There are 3 attribute values that control memory management for any #synthesized setters. The first is retain which will automatically send release to old values of the property, and retain to the new values. This is very useful.
The second is copy which will make a copy of any values passed in rather than retaining them. It is good practice to use copy for NSString because a caller could pass in an NSMutableString and change it out from under you. copy will make a new copy of the input which only you have access to.
The third is assign which does a straight pointer assign without calling retain/release on the old or new object.
Lastly you can also use the readonly attribute to disable the setter for the property.
I use properties for the interface part - where the object interfaces with other objects
and instance variables are stuff that you need inside your class - nobody but you is supposed to see and manipulate those.
By default, a readwrite property will be backed by an instance variable, which will again be synthesized automatically by the compiler.
An instance variable is a variable that exists and holds its value for the life of the object. The memory used for instance variables is allocated when the object is first created (through alloc), and freed when the object is deallocated.
Unless you specify otherwise, the synthesized instance variable has the same name as the property, but with an underscore prefix. For a property called firstName, for example, the synthesized instance variable will be called _firstName.
Previously people use properties publicly and ivars for private usage, but since several years ago, you can also define properties in #implementation to use them privately. But I'd still use ivars when possible, since there are less letters to type, and it runs faster according to this article. It makes sense since properties are mean to be "heavy": they are supposed to be accessed from either generated getters/setters or the ones manually written.
However, in recent codes from Apple, ivars are not used anymore. I guess because it's more like objc rather than C/C++, plus it's easier to use properties with assign, nullable, etc.
Objective-C Property vs Instance variable (iVar)
[Swift variable, property...]
Instance variable
#interface SomeClass: NSObject
NSString *someVariable;
#end
Property
#interface SomeClass: NSObject
#property (nonatomic, strong) NSString *someVariable;
#end
Property uses Instance variable inside. property = variable + bounded getter/setter. It is a method call with variable syntax and access
#property generates getter and setter methods(accessor methods) which uses backing ivar(aka backing field) which you can use via underscore _<var_name> (_someVariable).
Since it calls a method - method dispatch mechanism is used that is why KVO[About] can be applied
When you override accessor methods backing iVar is not generated that is why you can declare a new property explicitly or use #synthesize[About] to generate a new one or link with existing
#import "SomeClass.h"
#interface SomeClass()
#property (nonatomic, strong) NSString *someVariable;
#end
#implementation SomeClass
- (void) foo {
//property getter method
NSString *a1 = self.someVariable; //NSString *a1 = [self someVariable];
//property setter method
self.someVariable = #"set someVariable"; //[self setSomeVariable:#"set someVariable"];
//iVar read
NSString *a2 = _someVariable;
//iVar write
_someVariable = #"set iVar";
}
//if you overriding someVariable getter and setter the iVar(_someVariable) is not generated, that is why you can:
//1. create some variable explicitly
NSString *_someVariable;
//or
//2. use #synthesize
#synthesize someVariable = _someVariable;
//overriding
- (NSString*) someVariable {
return _someVariable;
}
- (void)setSomeVariable: (NSString*) updatedSomeVariable {
_someVariable = updatedSomeVariable;
}
#end
[property attributes]