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
There are lots of helpful information available on internet, so just share some notes I found useful during application development, to contribute back to the community. Jonathan in Toronto
Sunday, October 30, 2011
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
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
Tuesday, September 13, 2011
Variable length arguments for javascript method
When creating javascrip method, if the parameters passed by caller may be different by any reason, an easy solution is just defining the parameters to empty, then inside the javascript method, accessing the actual parameter from the implicit argument variable.
The arguments variable inside the called function is an array containing the values of all the arguments passed to the function by caller, as shown in the following example:
function test()
{
alert(arguments[1]);
}
test("0","1","2");
John
The arguments variable inside the called function is an array containing the values of all the arguments passed to the function by caller, as shown in the following example:
function test()
{
alert(arguments[1]);
}
test("0","1","2");
John
Missing closing script tag in html causes javascript runtime error: Object expected
An runtime error: Object expected was returned when testing a simple function in html page's onLoad method. It turns out the error is due to missing closing script tag included
[head]
[script src="testcase.js" /]
[script type="text/javascript"
function callme() {alert("hi");}
[/script]
[/head]
[body onload="callme()"]
After adding the closing tag as shown below, the javascript method callme works properly.
[head]
[script src="testcase.js"] [/script]
[script type="text/javascript"
function callme() {alert("hi");}
[/script]
[/head]
[body onload="callme()"]
John
[head]
[script src="testcase.js" /]
[script type="text/javascript"
function callme() {alert("hi");}
[/script]
[/head]
[body onload="callme()"]
After adding the closing tag as shown below, the javascript method callme works properly.
[head]
[script src="testcase.js"] [/script]
[script type="text/javascript"
function callme() {alert("hi");}
[/script]
[/head]
[body onload="callme()"]
John
Wednesday, June 15, 2011
Property Attribute for iphone App
The following are some attribute used for property definition:
[assign]
This attribute indicates the property uses assignment in the property’s setter. No release to be called to the old value, and no retain to be called on the new value.
[retain]
This attribute indicates the property calls release to the old value, and retain on the new value.
[copy]
This attribute indicates the property calls release to the old value, and then allocate and copy a new object to the new value. The copy operation will retain on the newly created object.
[nonatomic]
This attribute indicate that the property’s accessor methods are not thread safe.. So do not access this property from multi-threads
[assign]
This attribute indicates the property uses assignment in the property’s setter. No release to be called to the old value, and no retain to be called on the new value.
[retain]
This attribute indicates the property calls release to the old value, and retain on the new value.
[copy]
This attribute indicates the property calls release to the old value, and then allocate and copy a new object to the new value. The copy operation will retain on the newly created object.
[nonatomic]
This attribute indicate that the property’s accessor methods are not thread safe.. So do not access this property from multi-threads
When the variable or data member needs to be released for iPhone
Basically, all variable and data members that is derived from NSObject needs to be explicitly release in iphone applications. When the variable or data member goes out of scope, the application or OS will not release it automatically, as all variable or data members are allocated in heap instead of stack. There is no concept of stack in objective C, so none of the variable or data member can be cleaned up automatically.
For local variable of NSObject in a method, releasing the variable before exiting the method.
For property, as the setter will release its current property value and retain the new value, so need to release the property value when the object instance is deallocated.
For instance variable, same as property, release the value when the object instance is deallocated
Certainly, if the variable or variable is changed in the middle, the old value needs to be released and the new value needs to be retained.
There are some exceptions due to compiler optimization, particularly for NSString objects, which may cause confusion to developers. For example, NSString object created with
[[NSString alloc] initWithString@"abc"] or [NSString StringWithString] has a retain count of 2147483647 instead of 1. The reason is the returned NSString just points to immutable constant NSString object passed in, which does not need to be released. However, NSString object created with [[NSString alloc] initWithUTF8String:"abc"] will need developer to release it. The IOS reference document does not mention anything about this kind of difference, and the only clue available is checking retainCount of the returned object.
In addition, based the memory management rules from Apple, release method should be called for [[NSString alloc] initWithString@"abc"], althoug we know actually it does nothing.
- You take ownership of an object if you create it using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy” (for example, alloc, newObject, or mutableCopy), or if you send it a retain message.
- You use release or autorelease to relinquish ownership of an object. autorelease just means “send a release message in the future” (specifically: when the used autorelease pool receives a drain message—to understand when this will be, see “Autorelease Pools”).
For local variable of NSObject in a method, releasing the variable before exiting the method.
For property, as the setter will release its current property value and retain the new value, so need to release the property value when the object instance is deallocated.
For instance variable, same as property, release the value when the object instance is deallocated
Certainly, if the variable or variable is changed in the middle, the old value needs to be released and the new value needs to be retained.
There are some exceptions due to compiler optimization, particularly for NSString objects, which may cause confusion to developers. For example, NSString object created with
[[NSString alloc] initWithString@"abc"] or [NSString StringWithString] has a retain count of 2147483647 instead of 1. The reason is the returned NSString just points to immutable constant NSString object passed in, which does not need to be released. However, NSString object created with [[NSString alloc] initWithUTF8String:"abc"] will need developer to release it. The IOS reference document does not mention anything about this kind of difference, and the only clue available is checking retainCount of the returned object.
In addition, based the memory management rules from Apple, release method should be called for [[NSString alloc] initWithString@"abc"], althoug we know actually it does nothing.
- You take ownership of an object if you create it using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy” (for example, alloc, newObject, or mutableCopy), or if you send it a retain message.
- You use release or autorelease to relinquish ownership of an object. autorelease just means “send a release message in the future” (specifically: when the used autorelease pool receives a drain message—to understand when this will be, see “Autorelease Pools”).
Sunday, May 29, 2011
Static variable in C/C++
Thanks to the iPhone development platform, the C++ once again gets the notice of mobile developers. This post talks few issues about static keyword in c/c++.
1. Using static for variable in file scope
If the same named variable is defined in multiple files, compiler will report an error due to the duplicated definition. Adding static for the variable definition will make the variable's scope to the current file, so that they will not conflict with each other. Note, the static variable defined in each file has its own instance. Changing the static variable's value in one file will not affect another file's variable value.
If you want to share the same instance, using extern keywork.
2. Using static for variable in class scope
This is quite easy to understanding, since it is similar to .net or java. The variable belongs to the class instead of a particular class instance.
3. Using static for variable in method scope
The variable will be initialized once, and each time when the mothod gets called, the same instance will be used. It is more useful in c, as in c++, we can just define a class member to do the same thing.
In all cases, if adding const in the definition, then the variable can not be updated once it is initialized.
Jonathan
1. Using static for variable in file scope
If the same named variable is defined in multiple files, compiler will report an error due to the duplicated definition. Adding static for the variable definition will make the variable's scope to the current file, so that they will not conflict with each other. Note, the static variable defined in each file has its own instance. Changing the static variable's value in one file will not affect another file's variable value.
If you want to share the same instance, using extern keywork.
2. Using static for variable in class scope
This is quite easy to understanding, since it is similar to .net or java. The variable belongs to the class instead of a particular class instance.
3. Using static for variable in method scope
The variable will be initialized once, and each time when the mothod gets called, the same instance will be used. It is more useful in c, as in c++, we can just define a class member to do the same thing.
In all cases, if adding const in the definition, then the variable can not be updated once it is initialized.
Jonathan
Subscribe to:
Posts (Atom)