Sunday, October 30, 2011

Property and Synthesize in ObjectC and Xcode

Property in ObjectC and xCode is quite different from what java or C# or C++ uses property. The following highlights the difference
1. What "@property float myValue;" does
When defining property myValue in header file, it says, there will be a myValue and setMyValue method available in implementation file. In addition, those two methods can be invoked using myObject.myValue to get and set.

Notice when property is defined, there is no data member involved, the value is totally controlled by myValue and setMyValue method

Update to now, everything is quite clear, and nothing is that different from C# or java.

2. What "@synthesize myValue;" does
@synthesize is totally new to java or c#. It does more harm then help to objectC. As program is not about simplifying of coding, it is about logic consistence. It is better to let developer explicitly specifies the expected behavior than magically doing so underneath.

So what @synthesize does as shown below?
head file:
@property float myValue;"

implementation file:
"@synthesize myValue;"

The above code silently create the imaged implementation of myValue and setMyValue for the myValue property. And it also silently create the data member to hold the myValue's data, so that the code can first set the value and then get the value back without defining a data member to store the value. Developers actually do not know where data is stored, they just know it is stored in somewhere.

Now let add a data member myValue in the header file, and see what magic will happen. As long as the data member's type and name match the property's type and name, then @synthesize will automatically associate the imaged implementation to the data member, so the data are actually stored in the new data member.

Up to now, things still look fine although not appreciated. It really starts to mess up when adding property method implementation as shown in the following code:
Header file
@interface Property : NSObject {
float myInsideValue;
}
@property float myValue;
-(float) myMethod:(float)m;
@end

Implementation file:
@implementation Property
@synthesize myValue;

- (float) myValue
{
return myInsideValue;
}

- (void) setMyValue:(float) v
{
myInsideValue =v;
}

-(float) myMethod:(float)m
{
myValue = m;
return myValue;
}
@end

The major problem is @synthesize silently adds a imagined data member when myValue is accessed inside the interface implementation file, so inside myMethod accessing myValue does not go through the property methods. While, when myValue is accessed outside the interface implementation file, myValue is accessed through property method. As the result, inside the implementation file, myValue's value is different from myInsideValue's value.

In order to avoid this kind of confusion, a simple rule is do not use property method and synthesize together, and it is preferred to use property method to be consistent with java or c#. If subclass for property is involved, it is much better to deal with property method than the "smart" syntheisze syntex.


3. Inside the class only use data member

4. property and subclass

Sunday, October 2, 2011

Upgrade the version of Blackberry persistent store class

When upgrading the version of Blackberry persistent store, like adding or removing a instance member in the persistent class, the saved persistent data will be automatically deleted by system.
To handle the version upgrading while storing the data in a single version instead of multiple versions of persistent classes, the application needs to keep the code of all older versions of persistent store in order to load the older data, and also upgrade the old version of data to latest version.

The logic are as follows:
VersionKeyArray =
{
OlderVersionKey1;
OlderVersionKey2;
LatestVersionKey3;
}

CurrentVersionKey = VersionJeyArray.LatestVersionKey3;
while (currentVersionKey != NULL)
{
get stored persistent object;
if (persistent object != NULL )
{
if ( is not the latest version )
{
read the older version of persistent data
Convert to the new version, this may involves crossing multiple versions
persist the new version of data
delete the older version of data
break;
}
}
go to the next older version key
}

//when the code gets here, we know we have the latest version of data
process the load persistent data if it is not null