Objective-C - Data Encapsulation, Synthesized Accessors and Dot Notation (iOS 6)

From Techotopia
Jump to: navigation, search
PreviousTable of ContentsNext
The Basics of Object Oriented Programming in Objective-CThe Basics of Modern Objective-C


Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book


In the preceding chapter we looked at the basics of creating and working with objects in Objective-C. In this chapter we will look more closely at accessing data encapsulated in classes through the use of synthesized accessor methods, properties and dot notation.


Contents


Data Encapsulation

In the previous chapter we mentioned briefly the concept of data encapsulation whereby data is contained within objects and is not accessible by any means other than via methods defined on the class. In our BankAccount class example we defined two instance variables and then wrote some methods to get, set and display those values. In this chapter we will look at some alternate programming techniques to access the data encapsulated in a class.

Properties, Synthesized Accessor Methods

Accessor methods (also referred to as getters and setters) are methods belonging to a class that allow the programmer to get and set the values of instance variables contained within that class. In our BankAccount example covered in the previous chapter we wrote accessor methods to get and set the bank account number and bank balance variables. As you can probably imagine, having to write these methods for large numbers of complex classes will ultimately prove to be time consuming. Fortunately, Objective-C provides a mechanism that automates the creation of accessor methods. These are called synthesized accessor methods and are implemented through the use of the @property directive. The following code demonstrates a modified version of our BankAccount class @interface definition file with the two getters and setters we originally wrote removed and the two instance variables declared as properties via the @property directive. Note also the removal of the braces ({}) around the instance variables when they are declared as properties:

#import <Foundation/Foundation.h>

@interface BankAccount: NSObject
@property double accountBalance;
@property long accountNumber;
-(void) setAccount: (long) y andBalance: (double) x;
-(void) displayAccountInfo;
@end

Note that because the two properties are of different data types (double and long) it was necessary to declare them on separate @property lines. Had they been of the same data type we could have placed them on the same line, separated by commas:

@property int x, y;

Having created the properties, the question that now arises is what the synthesized accessor methods will be named when they are generated by the compiler.

In assigning a name to a synthesized accessor setter method, Objective-C takes the name of the instance variable (for example accountBalance), capitalizes the first letter (AccountBalance) and then pre-fixes it with set (setAccountBalance). For example:

BankAccount *account1;
account1 = [[BankAccount alloc] init];

[account1 setAccountBalance: 1500.53];
[account1 setAccountNumber: 34543212];

In the case of the getter method, this simply adopts the name of the property. For example, the getter method name for the accountNumber property is also accountNumber:

long myAccount = [account1 accountNumber];

Accessing Property Instance Variables

As we have seen, the properties of a class instance can be accessed using synthesized accessor methods. It is also generally necessary to access properties from within the instance methods of the class. Take, for example, the code for our displayAccountInfo instance method:

-(void) displayAccountInfo
{
        NSLog (@"Account Number %ld has a balance of %f", 
         accountNumber, accountBalance);
}

With the two instance variables wrapped in properties, the above code will fail to compile with an error stating that the accountNumber and accountBalance variables are undefined. The reason for this is that when using properties, the underlying instance variable is synthesized using the instance variable name prefixed with an underscore. For example:

-(void) displayAccountInfo
{
        NSLog (@"Account Number %ld has a balance of %f", 
         _accountNumber, _accountBalance);
}

The Modified Bank Account Example

The code for the example Bank application, after being adapted to use properties and synthesized accessors, now reads as follows:

BankAccount.h:

#import <Foundation/Foundation.h>

@interface BankAccount : NSObject
@property double accountBalance;
@property long accountNumber;

-(void) setAccount: (long) y andBalance: (double) x;
-(void) displayAccountInfo;
@end

BankAccount.m:

#import "BankAccount.h"

@implementation BankAccount
-(void) setAccount: (long) y andBalance: (double) x;
{
        _accountBalance = x;
        _accountNumber = y;
}

-(void) displayAccountInfo
{
        NSLog (@"Account Number %ld has a balance of %f", 
          _accountNumber, _accountBalance);
}
@end

main.m:

#import <Foundation/Foundation.h>
#import "BankAccount.h"

int main(int argc, const char * argv[])
{
    @autoreleasepool {
      BankAccount *account1;

      account1 = [BankAccount alloc];
      account1 = [account1 init];
      [account1 setAccountBalance: 1500.53];
      [account1 setAccountNumber: 34543212];

      [account1 displayAccountInfo];

      [account1 setAccount: 4543455 andBalance: 3010.10];

      NSLog(@"Number = %ld, Balance = %f",
                  [account1 accountNumber],
                  [account1 accountBalance]);
    }
    return 0;
}

The true power of properties is most noticeable in the BankAccount.m implementation file where the use of properties has reduced the number of methods that needed to be implemented from six down to two.

Objective-C and Dot Notation

Those familiar with object oriented programming in Java, C++ or C# are probably reeling a little from the syntax used in Objective-C. They are probably thinking life was much easier when they could just use something called dot notation to set and get the values of instance variables. The good news is that one of the features introduced into version 2.0 of Objective-C is support for dot notation.

Dot notation involves accessing an instance variable by specifying a class instance followed by a dot followed in turn by the name of the instance variable or property to be accessed:

classinstance.property

For example, to the get current value of our accountBalance instance variable:

double balance1 = account1.accountBalance;

Dot notation can also be used to set values of instance properties:

account1.accountBalance = 6789.98;

A key point to understand about dot notation is that it only works for instance variables for which synthesized accessor methods have been declared. If you attempt to use dot notation to access an instance variable for which no synthesized accessor is available the code will fail to compile with an error similar to:

error: request for member 'accountBalance' in something not a structure or union

Summary

Data encapsulation involves the enclosure of data members within a class whereby access to that data is controlled through the methods of that class. When using instance variables, it was necessary to manually write getter and setter accessor methods to allow access to encapsulated instance variables. By wrapping those instance variables in properties, however, the compiler can be used to automatically synthesize these accessor methods for us thereby saving considerable programming time and effort.

This chapter has also covered the concept of using dot notation to access the data elements of a class instance, a concept that will be familiar to those used to programming in languages such as C++, C# or Java.


Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book



PreviousTable of ContentsNext
The Basics of Object Oriented Programming in Objective-CThe Basics of Modern Objective-C