I recently moved to doing BlackBerry development at work which required me to go through setting up a new environment. I had successfully setup iPhone and Android environments by simply following the directions on their web sites. Not surprisingly, Apple has the easiest development environment to get setup. Google had a few more steps but made up for it with good documentation. To get started on Blackberry development I installed a bunch of software from this page: Eclipse for Blackberry Development, Blackberry Java Development Environment (JDE), Torch Simulator, MDS Simulator. Ok good to go. I was able to build our product and run it on a simulator.Next I started playing around with the app. Setting breakpoints and getting an idea of how things were plugged together. I wanted to try out the voice search feature and thought the simulator would use the PC mic but it was not working. I figured it should be easy to load the app on a device and eliminate the simulator as the cause of the problem. The JDE comes with a tool called JavaLoader for placing builds on the device. I plugged the device into the computer and ran the tool. It dumped info to the terminal of what it was doing and left me with an error message: HRESULT: 80040154. With a quick search I found that error code meant the a COM class could not be instantiated. I figured I probably did not install the software which allowed for communication with the device over USB. But what was it? With COM to create an object you pass in a GUID and bam you have yourself an instance of some class (an oversimplification but good enough for this). Underneath the hood the program is really digging through the Windows registry looking for that GUID. If I could find that GUID I could easily find what I was missing with a quick web search. To find the GUID I fired up procmon and reran the JavaLoader program. Procmon is magic in a box. It shows all the different events taking place with the file system and registry for the whole system or a particular process. It helped me find the GUID in question as seen in the picture below:
I searched for BA3D0120-E617-4F66-ADCA-585CC2FB86DB and found a stackoverflow entry indicating that Blackberry Desktop Manager needed to be installed. Once I installed it everything work as expected.Lesson today: Good tools make life better.
Objective-C features anonymous functions via what they call blocks. I was a little fuzzy on the memory management rules of blocks at first. The basic rules are: the block structure is stack allocated and blocks retain Objective-C objects they reference until the block is deallocated. In order to keep the block around beyond the lifetime of a stack frame the block must be copied to the heap. All of the objects directly referenced within the block will be retained. When the block is released those objects will also be released. Keep in mind the retained objects may have weak references to other objects that may end up getting freed before one would expect. For example, an objects delegate is typically not retained. A simple mistake would be to perform an asynchronous action which causes a view to update but has the possibility of the delegate being released before that action has the opportunity to complete. With the Flickr app I spoke of previously I messed up on both rules. First, my block referenced tableView whose delegate was the view controller. With the code below it will likely fail if the user backs away before all the thumbnails finish loading.
Once the user backs away from the table’s view controller it will be released. It is possible the queue will still be downloading thumbnails. Once a thumbnail is downloaded the block passed to thumbnailWithBlock will be called and attempt to update the table only to have the program crash. Instead of sending the reload message to tableView I send the reload message to self.tableView. In this case self is the view controller for the table view and since it is now reference in the block it will be retained for later use.After using Grand Central Dispatch (GCD) to perform the image fetching I wanted to see how it could be done with NSURLConnection. NSURLConnection handles all of the networking on a separate thread. It notifies the UI thread via various delegate methods of the download progress. I simply changed the thumbnailWithBlock on the Photo object to use NSURLConnection and store a pointer to the block object for use later. When the download finished I called the block with the downloaded data but the program crashed. The reason was I had failed to copy the block to the heap and was getting the EXC_BAD_ACCESS error. The fix was to send a copy message to the block and be sure to release it after using it with the downloaded data.Once I figured that all out I wondered how GCD handled blocks. It must copy them or else it would be getting EXC_BAD_ACCESS errors. Me being curious I went and looked and sure enough they copy the blocks before using them.
I was toying around with MapKit today and I am pretty sure I found a bug. MapKit renders an extra line along the equator if a polyline's point has a latitude of zero or an extra line along the prime meridian if its longitude is zero AND if the line width is less than or equal to 1.0. The code snippet to reproduce the issue can be found here: https://gist.github.com/808845. And also a screenshot of the result: