2013-08-23

Nil Out Views in iOS

Before iOS 6, iOS would take the liberty of deleting any view controller’s view not currently on screen upon a low memory situation. As of iOS 6, Apple decided it would remove the memory-intensive backing stores of the graphical display, and thereby free up some memory, without bothering the app developer. So from the app developer’s point of view, the view remains intact. In actuality, iOS recreates the graphical backing stores when the affected view re-appears. Now iOS 6 no longer invokes either method you may have implemented: viewWillUnload & viewDidUnload.

You can recreate the old behavior. As always, your view controller receives a message about low memory by having its didReceiveMemoryWarning method invoked. You may nil out the controller's view. Be sure to check first that the view is not currently on screen. As always, the  didReceiveMemoryWarning invocation is an opportunity for you to clear unnecessary collections and to close other memory-intensive resources, all in an effort to free up memory.

When the view returns to the screen, you must of course recreate the view and restore the needed resources. Do so in your implementations of the loadView or viewDidLoad methods.

Example code:
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // While off-screen, dispose of the controller's view as well as any memory-intensive variables, collections, and resources that can be recreated. 

    NSLog(@"TRACE - %s:%d someObject=%@", __func__, __LINE__, self);  // If you want to log this for educational purposes.
    if( [self.view window] == nil ) { // Verify view is not on-screen.
        [myCollection removeAllObjects]; // Clear a collection.
        self.myImageView = nil; // Clear a resource.
        self.view = nil; // Re-creating pre-iOS 6 behavior to clear view.
    }

2013-08-20

Poor Yahoo!

I just spent a couple hours trying to explain and fix this error:
<Error>: CGAffineTransformInvert: singular matrix.
…reported in my app's log while I was testing my use of the WebKit widget (UIWebView class) to display HTML.

The "CG" means CoreGraphics, Apple's intense pixel-bending technology. One fellow on the internets says the issue is related to matrix math:
Probably you tried to use singular transformation matrix somewhere in your code. You should check your transformation matrices and avoid matrices like:
0 0 0
0 0 0
0 0 1
and others - check out Google how to tell singular 3x3 matrix (hint: it has determinant = 0).
Blah, blah, blah… All I did was try to load a web page. I'm not doing any graphics work.

I tried all kind of folk remedies related to my use of the UIWebView widget, but nothing worked.

Long story, short…

For this testing, I had randomly picked "http://www.Yahoo.com/" out of thin air as an arbitrary page. This error occurred repeatedly on every run. Eventually I switched to Google.com, no problem. Reuters.com, no problem. SeattleTimes.com, no problem. Go back to Yahoo.com, problem. And problem happens repeatedly while scrolling.

I'm guessing that Yahoo is doing some kind of screwy HTML or JavaScript, probably manipulating images or the page itself graphically, and thereby invoking CoreGraphics and generating the error.

Poor Yahoo can't seem to get anything right anymore.

2013-08-15

Automatically Archive Your Development Project Folder

I am so happy to finally find an extremely simple way to automate the simple chore of creating a compressed zip copy of my development project folder. I do this daily as a backup of my work.

I've yet to master source code control systems. Even if I did, those systems are just as good at destroying source code as they are at saving it. So even with BitBucket & Mercurial, for example, I would still want some simple zip copies of my entire project folder copied over to flash drives or other storage place.



The answer is Automator. This tool is bundled with every Mac. Built on top of AppleScript, Automator has pre-built tasks that you are likely to perform in the real world. One of those tasks is Create Archive. Bingo!

Using Automator is shockingly easy. Just drag-and-drop your desired tasks into a list. The tasks automatically chain together, the previous feeding into the next.

The main downside of Automator is also its virtue: Simplicity. While the various task panels offer a few options, they are indeed few. For example, I might want to use UTC time rather than local time when time-stamping each archive. No go. The workaround would be to write AppleScript code, and call that as a task.

Here is a screen shot of what you want to end up with if, like me, you want to create an archive of a folder, append current date and time to the .zip file, and store it in a "backups" folder.