Lazy Loading in Ionic 3

What is Lazy Loading?
  • Angular is a one page app.
  • Without lazy loading, all pages are loaded at the start of the app. With lazy loading, a page is loaded only when it is needed.
  • Therefore, for app with many pages, lazy loading allows faster initial load of the app, which should give better user experience.
How to do it in Ionic 3?

Briefly

  1. Add “@IonicPage()” decorator in every lazy-loaded page
  2. Create a module file, which imports “IonicPageModule”
  3. This page is not imported from anywhere. It is referred by calling its name as string
    e.g. navCtrl.push(‘ComponentName’) instead of navCtrl.push(ComponentName)

In more details

When a page has @IonicPage() decorator, the compiler knows that the page is a lazy-loaded page. For example, I have BookingPage defined in booking.ts


import { IonicPage } from 'ionic-angular';
...
@IonicPage()
@Component({
  selector: 'page-booking',
  templateUrl: 'booking.html'
})
export class BookingPage {
  ...
}

The compiler knows that the above is a lazy loaded page. The compilation will automatically look for booking.module.ts, which imports
IonicPageModule.forChild(BookingPage). So we need to create the module like that below.


import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { BookingPage } from './booking';
...

@NgModule({
  declarations: [
    BookingPage,
    ...
  ],
  imports: [
    IonicPageModule.forChild(BookingPage),
    ...
  ],
  exports: [
    BookingPage,
    ...
  ]
})
export class BookingPageModule { }

Both the above booking.ts and booking.module.ts are not imported from anywhere. They are linked in the project internally by Ionic 3. We just need to have those two files.

As BookingPage is not imported from anywhere, how do we show it? It’s by calling its name as string. For example when it is to be shown using a navigation controller, we call:

navCtrl.push('BookingPage')

instead of

navCtrl.push(BookingPage)

As usual, nothing new here, many people have done this. Just my note. Have a great day!

Set to nil – Release

I was checking the consequences of setting a pointer to “nil” and calling “release” on object, in Objective-C when developing an iPhone application.

Here is my understanding.

CASE 1

Person * p = [[Person alloc] init];

NSLog(@"%d", [p retainCount]); // 1

Here, a Person object instance is created in a memory address.
Pointer p points to the memory address of the Person instance.
As set by the memory management in Obj-C. calling [p retainCount] gives 1.

CASE 2

Person * p = [[Person alloc] init];
[p release];

NSLog(@"%d", [p retainCount]); // Error

When [p release] is called, the retain count of the Person instance decreases by one and becomes 0 (As set by Obj-C’s memory management). As the retain count reaches 0 the Person instance is destroyed and its memory address can be claimed by other.

How about the pointer p?

Pointer p still points to the memory address of the destroyed Person instance.
Thus, calling [p retainCount] gives error because p points to memory address of a destroyed object.

CASE 3

Person * p = [[Person alloc] init];
p = nil;

NSLog(@"%d", [p retainCount]); // 0

First, a Person instance is created in a memory address.
Second, by setting pointer p to nil, the following happens: the Person instance is destroyed from its memory address and then pointer p points to nothing.
Why is the Person instance destroyed? It is the way Obj-C is, that is when a pointer pointing to a memory address of an object is set to nil, the object is destroyed, unless case 5 below occurs.

Calling [p retainCount] returns 0. The 0 here is not because the retain count decreases by one, but because a call by a nil pointer is just ignored although no error occurs. We can see the evidence in case 4.

The memory management, however, will detect a leak, because setting p to nil does not decrease the Person instance’s retain counter, and hence the retain counter remains 1, although the Person instance is destroyed (But I can’t seem to get the evidence for this in Leaks instrument, as it does not show the leak).

CONCLUDING CASE 2 AND 3

Person * p = [[Person alloc] init];
[p release];
p = nil;

This concludes case 2 and 3.

Some people suggests to set pointer p to nil after [p release]. The purpose is to prevent error when there is an unexpected method call on p later on.

In dealloc method, however, setting p=nil is not necessary, because in dealloc method such pointer p will be cleaned.

CASE 4

Person * p = [[Person alloc] init];
[p retain];

NSLog(@"%d", [p retainCount]); // 2

p = nil;

NSLog(@"%d", [p retainCount]); // 0

First, a Person instance is created in a memory address.
Second, by calling [p retain], the retain count of the Person instance increases by one, so [p retainCount] gives 2.

Third, by setting p to nil, the Person instance is destroyed from its memory address, and then pointer p points to nothing. Calling [p retainCount] now gives 0 because the call is just ignored (as that in case 3).

The memory management still records that the retain count is 2, however, and so a memory leak will be reported, although the Person instance is destroyed.

CASE 5

Person * p1 = [[Person alloc] init];
Person * p2 = p1;
p1 = nil;

NSLog(@"%d", [p2 retainCount]); // 1

Pointer p2 points to the memory address of the Person instance, which is the same memory address that pointer p1 points to.

When p1 points to nil, here the Person instance is not destroyed. Why? Because the memory address of the Person instance is still pointed by pointer p2. Therefore calling [p2 retainCount] gives 1.

If the intention is to destroy the Person instance, we need to call “release”, as in case 6 below.

CASE 6

Person * p1 = [[Person alloc] init];
Person * p2 = p1;
[p1 release];

NSLog(@"%d", [p2 retainCount]); // Error

As in the previous scenario, pointer p2 points to the same memory address of the Person instance as that pointed by pointer p1.

Calling [p1 release] causes the Person instance to be destroyed, because the retain count of the Person instance reaches 0 after being decreased by one.

But pointer p2, unfortunately, points to memory address of the destroyed object. Therefore, unlike in case 5, calling [p2 retainCount] gives error.

CASE 7

Person * p1 = [[Person alloc] init];
Person * p2 = p1;
[p2 retain];
[p1 release];

NSLog(@"%d", [p1 retainCount]); // 1
NSLog(@"%d", [p2 retainCount]); // 1

Now, modified from case 6, [p2 retain] is called before [p1 release]. When [p2 retain] is called, the retain counter of the Person instance increases by one, and becomes 2.

Then when [p1 release] is called, the retain counter of the Person instance decreases by one, and becomes 1. Because it does not reach 0, the Person instance is not destroyed, so that at this point both [p1 retainCounter] and [p2 retainCounter] give 1.

CASE 8

Person * p1 = [[Person alloc] init];
People * people = [[NSMutableArray alloc] init];
[people addObject:p1];

NSLog(@"%d", [p1 retainCount]); // 2

[p1 release];

NSLog(@"%d", [p1 retainCount]); // 1

Person * p = (Person *) [people objectAtIndex:0];

NSLog(@"%d", [p retainCount]); // 1

This case seems familiar: a Person instance is created, passed into an array, and then it is released.

When an array adds an object, the object automatically calls “retain”, increasing the retain count of the object by one.

Calling “retain” before [p1 release] is similar to that in case 7, the retain count of the Person instance becomes 2.

When [p1 release] is called, the retain count decreases by one, and becomes 1.

As the evidence for the above, get the object from the array and let it be pointed by a pointer p, then call [p retainCount]. Consistently, it gives 1.

Slightly out of topic here, we may ask when the retain count will reach 0, because otherwise a memory leak occurs. The objectAtIndex automatically calls “autorelease” on the object, so that the object will be destroyed eventually by an autorelease pool.

CASE 9

Person * p1 = [[Person alloc] init];
People * people = [[NSMutableArray alloc] init];
[people addObject:p1];
p1 = nil;

Person * p = (Person *) [people objectAtIndex:0];

NSLog(@"%d", [p retainCount]); // 2

Now, what if p1 is set to nil, instead of released (i.e. calling [p1 release] as in case 8)?

The Person instance is now being used by the People array. Its memory address is being pointed by a pointer somewhere (implemented by array). Therefore, similar to case 4, when setting p1=nil the Person instance is not destroyed. In addition, the retain count of the Person instance does not decrease by one, but remains 2. Thus, [p retainCount] gives 2.

When eventually the object is released (because objectAtIndex automatically calls autorelease), its retain count will become 1. Thus, here a memory leak will occur, because of not only the retain count being more than 0 but also the Person instance being not destroyed.

CASE 10

Person * p1 = [[Person alloc] init];
People * people = [[NSMutableArray alloc] init];
[people addObject:p1];

NSLog(@"%d", [p1 retainCount]); // 2

[p1 release];

NSLog(@"%d", [p1 retainCount]); // 1

[people replaceObjectAtIndex:0 withObject:[NSNull null]];

NSLog(@"%d", [p1 retainCount]); // Error

This case is slightly out of topic here. It just checks replaceObjectAtIndex method on the array.

With replaceObjectAtIndex, the object is firstly removed from the location in the array before being replaced. When removing an object from an array, “release” is automatically called on the object. Therefore, the “release” decreases the Person instance’s retain count by one, making it reach 0, leading to the Person instance being destroyed.

Therefore the last [p1 retainCount] call gives error, because pointer p1 points to the memory address of the destroyed Person instance.

Conclusion
Only when the object, to which a pointer points, has been destroyed in its memory address, can the pointer be set to nil safely. Otherwise, there are consequences, as described in case 3, 4, 5 and 9.

gPHPEdit – the PHP editor I choose

My search for a suitable PHP editor ended up with gPHPEdit.

The search began when jEdit, once an excellent editor I always used, often halted my work. When typing using jEdit, my keyboard was often locked up, so I couldn’t type anything in jEdit although all other system worked normally. This Sun forum let me know that this issue seemed to be something that many people had been waiting to be fixed. (It seemed to be a bug in Java Swing in Linux. Yes, I was using Linux – Fedora 6).

Browsing a bit, I found a list of PHP editors available, some of which had already been familiar to me.

First I tried Eclipse because I wanted to try the most recent version i.e. 3.3.1 (The last time I used Eclipse was about a year ago). I used PDT plugin to PHP-enable the Eclipse. The look and feel and the functionalities looked good. However, when I wanted to edit a PHP file whose extension was .module (I developed a Drupal file), the Eclipse didn’t syntax-highlighted the code although I had followed all instructions to PHP-syntax-highlight non .php files in Eclipse. Moreover, I felt quite heavy launching the Eclipse, which also consumed much of memory and CPU of my 512MB-RAM 1GHz-PIII laptop. I thought it was too big for only a PHP editor.

Then I tried KDevelop, which was actually already in my Fedora 6. It launched much quicker than Eclipse. However, I found the PHP codes were not easy to read, because some guides in the editor looked too distracting to me, and I could not remove the guides to make the codes clearer to read.

Next, I tried Bluefish, which had been in my Fedora 6. The launch was fast, it didn’t consume much memory and CPU of the laptop, and it seemed to be well established. But there were some things that I was not happy with. First, the directories shown nested at the left sidebar was too wide, so that to finally show the directory I was working with, the sidebar had to be widened much. Second, the functions in the list at the sidebar were not those in my PHP code, but function references as those in php.net. I needed to have a list of functions in my code, in which clicking a function in that list could bring me straight to that in the code. Well, I thought, if I got no other alternative I would go with Bluefish anyway.

Feeling a bit exhausted but was still curious, I walked through the list again.

Then I tried gPHPEdit. I picked it because the name gave me a sense that it was a Gnome version of phpEdit, a well known but non-free one. Although gPHPEdit’s last update, i.e. version 0.9.91, was in 2006, I downloaded it anyway. I installed it by compiling the source into my /usr/local directory. The compilation was quick, it seemed lightweight.

I entered “module” into “Recognized PHP file extensions” form. I set “fxd” sized 10 as the font of the editor.

Then guess what? Yes, gPHPEdit gave me what I needed. It provided a clear view of my codes, recognized different PHP file extensions, was quick to launch, didn’t consume much memory and CPU of the old laptop and provided a browser for all functions in my code (which could be turned on/off) in which clicking a function there would direct me straight to that in the code. Moreover, the user interface was just clear and simple to me. All those were just what I needed. In addition, actually it was able to syntax-highlight PHP, CSS, HTML, XML, Python, C/C++, Perl and SQL.

I stopped walking through the list, because all in all gPHPEdit satisfied my needs. It made my PHP coding more enjoyable and so I tended to be more productive compromising my time for searching a suitable PHP editor ๐Ÿ™‚ at least for now. To the developers: “Big thanks”.

Installing Drupal using XAMPP in iMac

I was trying to install Drupal in the iMac, using XAMPP. So I downloaded XAMPP for Mac OS X and installed it. Then I put my Drupal into the /Applications/xampp/xamppfiles/htdocs directory.But what I got in the browser (http://localhost/drupal) were some errors like internal server error, forbidden access and exhausted memory.To fix them, I did as follows:

  • Altered ย the “etc/httpd.conf” ย so that under the document root directory, the “AllowOverride” is set to “All”:
    Options Indexes FollowSymlinks ExecCGI Includes
    AllowOverride All
    Order allow, deny
    Allow from all
  • Make .htaccess readable, by chmod a+r .htaccess
  • In “etc/php.ini”, set memory_limit variable value to 64M (the default was 8M)

Restart the Apache and done, until further problem ๐Ÿ™‚

Fedora core 6 in my T23

I almost replaced my FC6 in my T23 because the fedora often hanged up. I have tried removing services, changing kernel versions, uninstalling suspicious packages, but none of them were successful.

Yesterday night I visited this forum and after identifying some of the clues there, now my FC6 seems to be running smoothly. It has been running for more than 8 hours now. Then I shared this in that forum.

The most recent Fedora is FC7 now, but it didn’t install well in my T23. So I am using FC6. I feel like FC6 will be the last Fedora in my T23. When later on someday FC6 is out-of-date, probably I will go with Ubuntu.

I let my eyes be wet writing this post, because I have been loyal to Fedora/Redhat since Redhat 5.1 in 1999!

SOA in Ministry of Education

educationHere I wrote my thoughts regarding SOA (Service Oriented Architecture) in Ministry of Education, which may be good to be shared.

Basically, I tried to identify issues in a ministry of education. Then I wondered whether computing system adopting SOA could contribute to addressing the issues. I consulted the issues from, first, notes made by Brotosiswojo who was an officer in the ministry of education in Indonesia for about 20 years. Also, I consulted some notes by Drost, whom, although I’ve never met, I admired. From his notes, and from hearing from other people’s stories, I think Drost is a person who has strong determination to improve the quality of life of people. Although the issues were in Indonesia, I believe to some extent they are also found in other countries.

Click here for the article, in PDF