Wednesday, February 1, 2012

This pointer and function pointer in javascript

As shown below, Java or c# will pass current "this" pointer from caller to callee implicitly

void caller()
{
callee(); //caller will be invoked on this pointer used to invoke caller
}


In Javascript, when calling callee() inside caller(), if the invoking object is not specified as this.callee(), it does not implicitly pass the current "this" pointer to invoke callee(). And the global Window object will be used as "this" to invoke function callee.

When invoking constructor in javascript, inside the constructor, the "this" pointer is the current class, not the window object.

Another related issue is, in javascript, function defined in one class can be assigned to another object as method, (Note function is a standalone unit of statements and a method is attached to an object and can be referenced by the this keyword), and when invoking the method from another object, its this pointer is the assigned object, and has nothing to do with the class or instance that defines the function.

Sample code:
function bar()
{
alert(this.constructor.name);
}

function somefunc()
{
alert(this.constructor.name);
}

function apple()
{

this.bar = somefunc;
bar(); //call global bar
his.bar(); //call somefunc

this.internalMethod = function() {
alert("internal method this: " + this.constructor.name);
}
}


//to test the above code, calling following method from html page script section
var myApple = new apple();
myApple.internalMethod(); //myApple is this pointer used to invoke the method
var me = myApple.internalMethod;
me(); //window is used as this pointer to invoke the method


Full js file for testing

function Apple() {
try {
alert("constructor: "+ this.constructor.name);
this.color = "red";
this.bar = somefunc;
bar();
this.bar();

this.internalMethod = function() {
alert("internal method this: " + this.constructor.name);
}

this.internalMethod();

this.getInfo();
}
catch (ex) {
alert("exception: " + ex);
}
}

Apple.prototype.getInfo = function() {
alert(this.color + ', type: ' + this.constructor.name);
};

function bar() {

alert("bar method this: "+ this.constructor.name);
}

// anti-pattern! keep reading...
function somefunc() {
this.getInfo();
alert("somefunc this: "+ this.constructor.name);
}

Full html file for testing

var myApple = new Apple();
myApple.internalMethod();
var me = myApple.internalMethod;
me();

Tuesday, November 8, 2011

Set a breakpoint in dependent library in XCode 4.2

In order to set a breakpoint in a dependent library and break at the main project, you will need first set the breakpoint in the library and then change the scope of the breakpoint to user.
Launch the main project will hit the breakpoint you just set in the library project.

Iphone simulator folder in Lion with Xcode 4.2

By default, the library folder under user is hidden in Lion with Xcode 4.2, so you will not be able to access the iPhone simulator folder shown below.

/Users/(your user name)/Library/Application Support/iPhone Simulator

To show the library folder, run the following command from terminal window:

chflags nohidden ~/Library/

Note the library folder must be the one under your name, not the one under root.

Saturday, November 5, 2011

Fresh installation of Lion on Mac without CD or USB stick

Lion has to be upgraded on Mac, however, you may want to have a fresh install of Lion to get rid of the old application or settings from the Snow Leopard. The following steps can be used to make a refresh Lion installation.
1. Upgrade Snow Leopard to Lion as Apple suggested from app store (paying for $29)
2. Reboot Mac while holding option key
3. Select the restore disk for starting
4. Select Disk Utility and erase the main hard disk drive. This may erase the old Snow Leopard.
5. Restore Lion, it will start a refresh Lion installation.

Cheers
Jonathan

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

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