Skip to main content

Deep Diving Objective-C Properties (Part 2)

Previous post of properties explained about the lifetime qualifiers. Today post will have exciting stuff about the other qualifier and some concepts about where to used these qualifier.

Threads and Properties:


Suppose you are working in multithreaded environment and two thread want to access the same property at same time. Thread A want to write and thread B is in middle of reading the property name. 
What happen which value thread B will get. ?

There are two qualifier which decide the behaviour in such condition.
1)  atomic (Default)
2) nonatomic

Atomic:


1) Default behaviour.
2) Ensure that one thread will access property or method at a time. (Inconsistency will be not there as atomicity). Thread B will get autorelease value always in the above case.
3) Does not ensure the thread safety of instance variable. Any other thread can access the instance variable bind to property. So instance variable in not thread safe only setter and getter is thread safe.
4) Performance wise it is slow. For thread safety it need to lock the flow so that other method cannot access the methods at a same time. It used similar mechanism as we used "synchronized block". We will look in more detail of method definition in case of atomic.

Suppose you are standing in queue for apple product as given below:


Atomic properties are like you are entering or accessing the apple store one by one using doors. So doors in our case are properties. Threads are accessing the instance variable using doors (Properties) one by one.

But what happen if somebody destroy or collapses the store nobody can enter the store.   
In similar manner if somebody release the instance variable while other thread accessing the instance variable. In that case the release will happen and application would be crashed Bad Excess :( . 

Example:
@property (retainNSString* name;
@property (atomic, retainNSString* city;


Nonatomic:

1) Not a thread safety for accessors. So in above case the result will be unpredictable. Thread B can get the autorelease value or the value set by Thread A. It is purely luck here and luck decided by the run time environment of objective -c . 
2) Faster performance in multithreaded environment. Even in a single thread case the performance is higher side with nonatomic. When your application is not multithreaded you  should use nonatomic.

Let us understand the case of non atomic and multithreaded environment:





Problem : In a room there is bulb with switch and there are 10 people standing outside the room. They will enter in the room and change the status of button (If a bulb is on the off it else on it).  
If people make a queue you can predict the behaviour of bulb at any time. If people just rush to room like below case:


Then prediction is impossible (Obviously every one can predict the behaviour in end by counting the number of person ;).
Similar is the case for non atomic. If number of threads accessing the same property at particular time then prediction is impossible. What value thread get when using the getter of the variable.

Example:

@property (nonatomic, retain)NSString* name;

So That all about Thread and Properties.


Performance Test:

Atomic and NonAtomic:

I tested the atomic and non atomic case by taking the reference from the blog:
I declare two properties  in Person class

Person.h


@interface Person : NSObject

@property (strong, nonatomic) NSString* name;
@property (strong, atomic) NSString*    city;

@end

Person.m

@implementation Person

@end

Then in my controller i write the following method:

- (void) testPerformanceResult{
    _person.name = @"Objective - C";
    _person.city = @"Apple";
    
    CFTimeInterval startNonAtomcTime = CACurrentMediaTime();
    
    for (int i=0; i<1000; i++) {
       [_person name];
    }
    
    CFTimeInterval endNonAtomicTime = CACurrentMediaTime();
    
    NSLog(@"1000 nonatomic accesses, t = %.9f seconds", endNonAtomicTime-startNonAtomcTime);
    
    CFTimeInterval startAtomicTime = CACurrentMediaTime();
    for (int i=0; i<1000; i++) {
       [_person city];
    }
    
    CFTimeInterval endAtomicTime = CACurrentMediaTime();
    
    NSLog(@"1000 atomic accesses, t = %.9f seconds", endAtomicTime-startAtomicTime);
}

For me atomic property always taking more time then non atomic. For 1000 run following is the result:

2015-01-12 12:54:59.119 Hello world[1546:47159] 1000 nonatomic accesses, t = 0.000019835 seconds
2015-01-12 12:54:59.120 Hello world[1546:47159] 1000 atomic accesses, t = 0.000050940 seconds

You can try by your self in your code :). As we can see there is not much time difference but until your application is not multithreaded you should use nonatomic. 



Permission Qualifier:

There are two qualifiers, which defined the access permission for properties. Whether you can write the value in properties or it is just read only for you.
1) readwrite (Default)
2) readonly


Readwrite:

1) Default Behaviour.
2) When you synthesize the property both setter and getter will be created.

Example:
@property (atomic,retain, readwrite)NSString*     city;

ReadOnly:

1) When you synthesize the property only getter will be created by the compiler.
@property (readonly)NSUInteger    SSNNumber;

Let us cover the important point about the properties which you should take care of it.

Important Point About Properties:

1) You cannot use new as prefix for any property name or you can change the getter name of the properties.

@property (nonatomic, retain, getter=city)NSString* newCity;

2) Default qualifier for properties are Atomic and strong in ARC. In case of primitive type the default qualifier is Atomic and Assign.

@property NSString*     city; //atomic and strong
@property NSUInteger    SSNNumber; //atomic and assign

3) You can use permission qualifier to make a property private. 

Person.h


@interface Person : NSObject

@property (atomic,retain, readonly)NSString*     city;


@end

Person.m

@interface Person ()

@property (atomic,retain, readwrite)NSString*     city;

@end

@implementation Person

@end


Done:). Property is readonly for the other object accessing the person attributes.
Next Post will cover the Block programming with properties.

Comments

Popular posts from this blog

What does enable bitcode do in Xcode

Background: Now days compilation process for any language is divided into two parts and same is applicable for objective c. Frontend Compiler (Clang) Backend Compiler (LLVM) Frontend Compiler (Clang):  Responsibility of front-end compiler is to take a source code and convert into intermediate representation (IR).  In case of clang it is LLVM IR.  Backend Compiler(LLVM):  Responsibility of backend compiler is to take a IR as input and convert into object code. LLVM input is bitstream of LLVM IR (Bitcode) and output is sequence of machine instruction(Object code). Each  cpu or processor has different set of  M achine   instruction, So  LLVM output is CPU dependent or it can be executed on specific CPU only.   There may be question in your mind that  1) What is the need to divide into these phases? 2) What is LLVM IR? Can we see the LLVM IR as Output? What is the need to divide into these phases? It is beneficial for both the programming language designer a

Asynchronous Request with NSOperationQueue

Today post is about how to run a asynchronous task in NSOperationQueue.  Generally we do not run a Asynchronous task in NSOperationQueue. It is also not recommended for any programmer to do that. This post is only for learning purpose what will happen if we schedule a asynchronous task in a queue and how can we complete that task:). So let us move to the learning: NSOperationQueue: In iOS NSOperationQueue is a class, which provide a way to perform operation concurrently. We also have others way to perform concurrent operation: 1) GCD 2) NSThread 3) pThread NSOperationQueue is a wrapper on GCD, which provides a very convenient way to execute operation concurrently. To create a Queue for Operation you have to simply allocate a object of the class: NSOperationQueue * opertionQueue = [[ NSOperationQueue alloc ] init ]; For this post let suppose you are making a queue to handle all Http request in your application. So i want to create a queue in Handler class

Everything about BLE with iOS Part1 (Introduction)

In this article we will learn how to turn your iPhone to behave as peripheral (who has data to send) or central (who receive the data). What is BLE (Bluetooth Low energy device) ? Bluetooth LE is a wireless personal area network technology like its previous incarnation, Classic Bluetooth. It can be use to transfer and receiving of the data. What is difference between Classic and LE ? BLE has low power consumption and low data transfer rate. BLE can support large number of slaves. On the other hand Classic (3.0) support maximum 7 devices connectivity. Unique feature of BLE is advertising  functionality,  So other devices can scan,  connect and  receive data from the advertising BLE device. Other difference is in classic you need to pair the devices first for the communication. Terms: Peripheral:  It is device which advertise the service. In client-server architecture form we can say peripheral is server which has data to send to client. The basic difference i