Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Open source Java iOS tools compared

Five free tools for developing iPhone and iPad applications in Java

  • Print
  • Feedback

Page 4 of 5

ARC on iOS

Automatic reference counting (ARC) on iOS 5 and higher places the compiler in charge of counting references, rather than the developer. ARC works the same as garbage collection except that it doesn't handle cycles, for instance in cases where an object contains a reference to another object, which (transitively) contains a reference to the first object. In this case a "dead" cycle of objects would be freed when using garbage collection, but not when using ARC. The solution provided by ARC is to denote some references as "weak" references so that they don't affect the reference count for an object. This can effectively break a cycle and allow these cycles of objects to be correctly freed when they are no longer referenced. See Resources to learn more.

As an example, consider this snippet from an Objective-C application that includes some code generated by XMLVM:

@interface NotesListController
    @property JAVA_OBJECT notes;
@end

Here we are declaring a property on an Objective-C class NotesListController to be of type JAVA_OBJECT. The problem is that Objective-C classes like NotesListController are reference-counted by the Objective-C runtime, but JAVA_OBJECT variables (the type used by XMLVM for all Java objects) are managed by XMLVM's garbage collector. Now, suppose you assign an object to a NoteListController, like so:

self.notes = ca_weblite_crossmobile_shared_Note_getNotes__();
    // calling static java method ca.weblite.crossmobile.shared.Note.getNotes()

The garbage collector has no knowledge that self.notes contains a reference to the object that was returned from the ca_weblite_crossmobile_shared_Note_getNotes__() method, so, if there are no other references to that object in the heap, the garbage collector may delete it, even though the NoteListController still has a reference to it, and still needs it. When NoteListController tries to use this object later on, that action will trigger a memory access violation.

The solution alluded to above is to make sure that the heap always includes a reference to the object until it isn't needed anymore. We could do this fairly easily by creating a simple "Auto-release pool" in Java as follows:

/**
 * Class to maintain references to Java objects in the heap.
 */
public class AutoReleasePool {
    private static Map<Object,Integer> referenceCounts = new HashMap<Object,Integer>();
    
    /**
     * Increments the reference count for an object.
     */
    public static void retain(Object o){
         Integer count = referenceCounts.get(o);
         if ( count == null ){
             count = new Integer(1);
         } else {
             count = new Integer(count.intValue()+1);
         }
         referenceCounts.put(o, count);
    }
    
    /**
     * Decrements the reference count for an object.
     */
    public static void release(Object o){
        Integer count = referenceCounts.get(o);
        if ( count == null ){
            return;
        }
        
        count = new Integer(count.intValue()-1);
        if ( count.intValue() <= 0 ){
            referenceCounts.remove(o);
        } else {
            referenceCounts.put(o, count);
        }
    }
}

Using this class, we would "retain" a JAVA_OBJECT when it is set as a property of an Objective-C class as follows:

  • Print
  • Feedback

Resources