TweetFollow Us on Twitter

The Road to Code: There's a Hole in your Bucket

Volume Number: 24 (2008)
Issue Number: 02
Column Tag: The Road to Code

The Road to Code: There's a Hole in your Bucket

Objective-C Memory Management

by Dave Dribin

Introduction

Welcome back to The Road to Code. In previous articles, we've talked about dynamic memory management and how to use malloc and free in C. We've also covered using alloc and release in Objective-C. Unfortunately, I left out a lot of the details of Objective-C memory management, mentioning only that alloc and release worked the same as malloc and free. This was a white lie, and the truth is that they are a bit more complicated. While the complications are a bit of a hurdle to overcome, they paradoxically make it easier on the programmer, in the long run.

Object Ownership

Let's assume, for a bit more, that the alloc method allocates memory for an object and the release method immediately deallocates it. For the simple programs we've written so far, it's easy to remember when to call release. Take this simple example where we use our Rectangle class in Listing 1:

Listing 1: Using the Rectangle class

#import <Foundation/Foundation.h>
#import "Rectangle.h"
int main (int argc, const char * argv[])
{
   NSAutoreleasePool * pool =
      [[NSAutoreleasePool alloc] init];
   Rectangle * rectangle;
   
   rectangle = [[Rectangle alloc] initWithLeftX   : 5
                                 bottomY   : 5
                                  rightX   : 15
                                   topY   : 10];
   printf("Area is %.2f\n", [rectangle area]);
   printf("Perimeter is: %.2f\n", [rectangle perimeter]);
   
   [rectangle release];
   
   [pool release];
   return 0;
}

We've allocated a Rectangle instance at the beginning of main so we just need to remember to call release to deallocate it at the end of main before it returns. However, as programs get larger and start running for longer periods of time, the task of how and when to release memory becomes daunting. You may have two objects that both are using the same Rectangle instance, for example, by showing the rectangle in two different windows. This would give you an object graph that looks like Figure 1:


Figure 1: Simple object graph

Both object_1 and object_2 have references to the same instance of a Rectangle class, rectangle. Which object, object_1 or object_2, has the responsibility to release rectangle when they get released and deallocated? If neither of them call release, then you end up in a situation like Figure 2.


Figure 2: Leaking an object

rectangle now exists with no other object pointing to it, so it is lost to the system and taking up memory. This is called a memory leak, and memory leaks are serious bugs. If you have memory leaks in a long-running program, such as a GUI application, then the program will be using more and more memory as it runs. Pretty soon, it could be using most of the memory in the system. This leads to a bad user experience, as memory is being used for dead and no longer used objects, instead of useful stuff.

Okay, so clearly not releasing used objects is a bad thing. But on the other end of the spectrum of memory problems, you can also over-release an object. Say that both object_1 and object_2 decide they should be responsible for releasing rectangle. Now, if object_2 is released and deallocated, it releases and deallocates rectangle along with it. You end up with a situation like Figure 3:


Figure 3: Dangling pointer

Oops! Now object_1 is pointing to memory that was previously used by rectangle, but has now been deallocated and returned to the system. This situation is called a dangling pointer. Dangling pointer bugs manifest themselves in strange ways and can be hard to track down. Since memory returned to the system may not be recycled and reallocated for other purposes right away, object_1 might be able to use rectangle after its death. It will continue to work...for a bit. But then, at some point, your program may start acting really strange or outright crash. Because the symptoms of the bug are delayed - the bug actually occurred where rectangle was prematurely released - these kinds of bugs are hard to squash.

In order to avoid both memory leaks and dangling pointers, we need to make sure that objects are only deallocated after all objects pointing to them are finished. One way to do this is with the concept of ownership. We can setup a system where every object is owned by one and only one other object, and only the owner is responsible for releasing the object. Also, object ownership can be transferred from one object to another. For example, take Figure 1 again. If object_1 owns rectangle, then when object_2 is deallocated it does not take rectangle with it. If, on the other hand, object_2 is the owner, it may pass ownership to object_1. Thus, when object_1 is deallocated, it will take rectangle with it.

As you can begin to see, even from this simple example, the concept of ownership can be hard to manage. How do you notify object_1 that it now owns rectangle? What if a third object, object_3, is created before object_1 is deallocated and it also uses rectangle? object_1 needs to somehow know about this and transfer ownership, instead of releasing rectangle upon deallocation. There are ways to manage the single ownership problem, but they can be difficult to get right. Thankfully, Objective-C gives us a better way.

Reference Counting

Instead of having single ownership, with one and only one owner, Objective-C embraces shared ownership. Thus object_1 and object_2 both own rectangle. rectangle does not need to know who its owners are; it just needs to keep track of the number of owners. When the number of owners drops to zero, then it's deallocated. The number of owners is called a reference count since it counts how many other objects reference (point to) it. I've modified the original object graph in Figure 4 to also show the reference count of rectangle. Thus when object_2 releases rectangle, it decrements the reference count from two to one. Since the reference count is still greater than zero, it is not deallocated and is available for object_1. When object_1 also releases it the reference count will be zero, and rectangle will finally be deallocated.


Figure 4: Reference count

This also fixes our situation where object_3, which also uses rectangle, is created before object_1 releases rectangle. The reference count for rectangle goes back up to two. Thus if object_1 releases rectangle, the reference count will be one and it will live until object_3 also releases it.

Okay, so that's the theory. How do you actually use reference counting in Objective-C? You've already been partially using it. All objects that inherit from NSObject (which are all objects) already contain a reference count. The release method does not deallocate the memory straight away, like the free function does. Instead, it subtracts one from the reference count, and only if the new reference count is zero will it deallocate the memory.

So release decrements (reduces) the reference count, but how do you increase the reference count? When an object is created with the alloc it is given a reference count of one. Thus, if we look at our program in Listing 1, you'll see why releasing rectangle deallocates it. If you need to increase the reference count there is a method called retain that does just this. Because Objective-C uses the retain method, the reference count in Objective-C is also called the retain count. Same thing, different name. In fact, you can even get the retain count of an object with the retainCount method. Listing 2 demonstrates the retain count.

Listing 2: Retain counts

#import <Foundation/Foundation.h>
#import "Rectangle.h"
int main (int argc, const char * argv[])
{
   NSAutoreleasePool * pool =
      [[NSAutoreleasePool alloc] init];
   
   Rectangle * rectangle;
   
   rectangle = [[Rectangle alloc] initWithLeftX   : 5
                               bottomY   : 5
                                rightX   : 15
                                 topY   : 10];
   
   printf("Retain count: %d\n", [rectangle retainCount]);
   
   [rectangle retain];
   printf("Retain count: %d\n", [rectangle retainCount]);
   
   [rectangle release];
   printf("Retain count: %d\n", [rectangle retainCount]);
   [rectangle release];
   [pool release];
   return 0;
}

When run, this program will output:

Retain count: 1
Retain count: 2
Retain count: 1

As an aside, while using retainCount can be interesting to see how reference counting works in Objective-C, you should only use it for debugging purposes. There are cases when the retain count is not telling the whole story, especially when autorelease pools (discussed below) come into play.

While Objective-C has built in support for shared ownership via reference counting, it is still an explicit step that all Objective-C programmers need to use properly. If you take away only one thing from this article, let it be this rule: every alloc and retain must be balanced by a corresponding release. Thus, in the example above, because we allocate the object and retain it once more, we need to release it twice.

Since it is a manual step, you can still get memory leaks if you forget to release an object after retaining it, and you can get dangling pointers if you release an object without first retaining it. Because the programmer must explicitly manage the reference count with retain and release, this is called manual reference counting. Other languages, such as Python, have automatic reference counting, where the language takes care of incrementing and decrementing the reference count for you. Alas, we Objective-C programmers have to do it manually, but at least we have it better than straight C programmers.

Retaining and Releasing in Accessors

Listing 2 is not a realistic usage of retaining and releasing objects, though, as you rarely retain an object for no reason. The reason you would retain an object is to take shared ownership in it. Let's create a new class called RectanglePrinter that holds onto a Rectangle instance and prints information about it. Listing 3 shows the interface for this class.

Listing 3: RectanglePrinter.h

#import <Foundation/Foundation.h>
#import "Rectangle.h"
@interface RectanglePrinter : NSObject
{
   Rectangle * _rectangle;
}
- (Rectangle *) rectangle;
- (void) setRectangle: (Rectangle *) rectangle;
- (void) printArea;
@end

To use this new class, let's use the test program in Listing 4.

Listing 4: RectanglePrinter test application

#import <Foundation/Foundation.h>
#import "Rectangle.h"
#import "RectanglePrinter.h"
int main(int argc, const char * argv[])
{
   NSAutoreleasePool * pool =
      [[NSAutoreleasePool alloc] init];
   
   Rectangle * rectangle;
   
   rectangle = [[Rectangle alloc] initWithLeftX   : 5
                               bottomY   : 5
                                rightX   : 15
                                 topY   : 10];
   
   RectanglePrinter * printer =
      [[RectanglePrinter alloc] init];
   
   [printer setRectangle: rectangle];
   [rectangle release];
   rectangle = nil;
   
   [printer printArea];
   [printer release];
   
   [pool release];
   return 0;
}

Let me point out a couple of things here. First, after calling setRectangle:, we release our instance, since we are no longer in need of it. This does not deallocate rectangle, though, since setRectangle: should take additional ownership and increase the retain count. We also set rectangle to nil after its release. nil is a special value that can be assigned to any object pointer, and it means the pointer points to no object at all. It's good practice to set your object pointers to nil after releasing them. While it won't matter if you've written your program without any bugs, it can help while debugging if you've made a mistake dealing with the retain counts.

Before diving into the implementation, there's a little more terminology to cover. Remember that instance variables are private and should only be used internally to the class. If you want to make an instance variable, like _rectangle, available outside your class, you should use methods to keep encapsulation intact. The pair of methods, rectangle and setRectangle:, expose the _rectangle instance variable publicly and are called accessor methods. The rectangle method is called a getter and setRecangle: is called a setter. The getter and setter pair of accessor methods is an important design pattern that we will be seeing more of in advanced Objective-C topics.

The implementation of RectanglePrinter shows how to use retain to take ownership for accessor methods, and is shown in Listing 5.

Listing 5: RectanglePrinter.m, first version

#import "RectanglePrinter.h"
@implementation RectanglePrinter
- (Rectangle *) rectangle
{
   return _rectangle;
}
- (void) setRectangle: (Rectangle *) rectangle
{
   if (rectangle == _rectangle)
      return;
   
   [_rectangle release];
   _rectangle = [rectangle retain];
}
- (void) printArea
{
   printf("Rectangle area: %.2f\n", [_rectangle area]);
}
@end

The rectangle method is simple: it just returns the _rectangle instance variable. This is how most getter methods should be implemented. The setRectangle: method is a bit more complicated, though. Notice that retain also returns the object, so you can perform the retain and assignment in a single step. You might be tempted to implement it as follows, by first releasing the current rectangle, and the retaining the new one:

- (void) setRectangle: (Rectangle *) rectangle
{
   [_rectangle release];
   _rectangle = [rectangle retain];
}

However, don't do it! This causes issues if the new rectangle is the same instance as the old one and the current retain count is already one. If this happens to be the case, releasing the object would cause it be deallocated before the retain happened, and you'd end up retaining a dead object. While this does not happen very often, it can happen, so it's wise to follow the pattern in Listing 5 and check for identical instances in all your setters. There are other correct ways of writing accessor methods, and indeed the "correct" way is still a topic of debate, but the pattern covered here covers the vast majority of situations.

Destructors

There's still one more bug lurking in this code. If calling release on a RectanglePrinter causes it to be deallocated, the Rectangle instance pointed to by the _rectangle instance variable is leaked. This is because we did a retain in setRectangle: but never paired this up with a release. What we really need is a way to be notified that our object is about to be deallocated so we can clean up any objects we're using. Thankfully, Objective-C calls a method named dealloc just before deallocating your object to give you a chance to do just that. Here's how we would implement it:

- (void) dealloc
{
   [_rectangle release];
   [super dealloc];
}

Because dealloc is called when the object is just about to be reclaimed for system usage, it is called a destructor. This terminology also pairs up with the init method being called a constructor, as we talked about in the previous article.

You may be wondering about the case where _rectangle is nil. Calling methods on objects set to nil does nothing at all. Thus, it's safe to call release on nil. This may seem odd if you're coming from a C++ or Java background where calling methods on an object set to null (their equivalent of nil) will cause your program to crash. This is one of the oddball Objective-C moments. Some people love it and some people hate it. Whatever your take, you may as well just live with it and embrace it, because it's not going to change.

You may also be wondering what _rectangle is set to if you never call setRectangle:. All instance variables are set to nil automatically by the default constructor (the init method of NSObject), so our code will work just fine. However, some people like to explicitly set objects to nil in a custom constructor. Listing 6 shows the complete implementation of RectanglePrinter, complete with constructor and destructor, accessor methods, and printArea.

Listing 6: RectanglePrinter.m, complete

#import "RectanglePrinter.h"
@implementation RectanglePrinter
- (id) init
{
   self = [super init];
   if (self == nil)
      return nil;
   
   _rectangle = nil;
   
   return self;
}
- (void) dealloc
{
   [_rectangle release];
   [super dealloc];
}
- (Rectangle *) rectangle
{
   return _rectangle;
}
- (void) setRectangle: (Rectangle *) rectangle
{
   if (rectangle == _rectangle)
      return;
   
   [_rectangle release];
   _rectangle = [rectangle retain];
}
- (void) printArea
{
   printf("Rectangle area: %.2f\n", [_rectangle area]);
}
@end

Retain Cycles

While reference counting is an effective technique to help deal with memory management, it can break down in one case. If two objects both reference each other, you end up with a situation where the retain count will never reach zero. This is because their retain counts will be stuck at one. Figure 5 shows how this can happen, where parent and child retain each other (see below):


Figure 5: Retain cycles cause memory leaks

When object_1 is deallocated, it releases its reference to parent. However, since child also references parent, the retain count can never reach zero, and we're stuck leaking an instance of both parent and child.

The trick to this is to have child contain a reference to parent, but not retain it. This is called a weak reference. By having child not retain parent, the reference count for parent is only one, as in Figure 6.


Figure 6: Using weak reference to break retain cycles

The key for this to actually work in practice is to explain, in a comment, that it is a weak reference, so that other developers will understand why a retain and release are not done on this reference. An example is shown in Listing 7.

Listing 7: Weak references

#import <Cocoa/Cocoa.h>
@class Parent;
@interface Child : NSObject
{
   // This is a weak reference.  Do not retain.
   Parent * _parent;
}
- (id) initWithParent: (Parent *) parent;
@end

Delayed Release

Sometimes getter methods do not simply return an instance variable. They may need to create a new object on the fly. Take this method that returns a Rectangle object that is a 4x4 square:

- (Rectangle *) square4x4
{
   Rectangle * square =
      [[Rectangle alloc] initWithLeftX   : 0
                         bottomY   : 0
                          rightX   : 4
                           topY   : 4];
   return square;
}

This looks very similar to any other getter method, except the caller is supposed to release the object when it is done with it. But how is the caller supposed to know this? We could document this in the code comments, but there's a high probably that people will miss this. Or we could rename the method such that it indicates object creation, such as newSquare4x4. But this limits our implementation choices in the future. What if we decided to use an instance variable to keep returning the same object for increased performance? We'd have to change our name back to square4x4 so as not to confuse the caller. The solution to this is to use the autorelease method supplied by NSObject. Thus the correct implementation of square4x4 is:

- (Rectangle *) square4x4
{
   Rectangle * square =
      [[Rectangle alloc] initWithLeftX   : 0
                         bottomY   : 0
                          rightX   : 4
                           topY   : 4];
   return [square autorelease];
}

The autorelease method is similar to release in that it will decrease the reference count, but at some point in the future instead of immediately. Thus, if the caller does not keep a reference to the return value, the object will be properly released. However, if the caller does retain the return value, then the retain count will still only be one. It will temporarily be two, but the delayed release causes the retain count to go back to one.

How does this autorelease thing actually work? The secret is autorelease pools, implemented by the NSAutoreleasePool class. Yup, those are the objects we see in our main class. When the autorelease method is called, the object gets added to the most current autorelease pool. When the pool is released, it also releases all objects in the pool. Thus, in our simple programs, the delayed release occurs just before the main application exits.

Because autorelease may by used internally by parts of the standard Foundation library, including NSObject, every application needs at least one autorelease pool active at all times. That's why the first thing our Objective-C programs do is set up an autorelease pool. We want to ensure an autorelease pool is in place before we start using any other objects. It's also why the last thing our program does is release the autorelease pool.

In GUI applications, you don't need to setup any autorelease pools. The standard Cocoa libraries take care of all this for you. For our command line applications, though, we need to take care of the autorelease pools, ourselves.

Autorelease and Class Methods

The methods we have been using so far only work on an instance of that class, thus they are called instance methods. There is another kind of method that does not require an instance of a class called class methods. These are declared using a plus ('+') instead of a minus sign ('-') as the first character:

+ (void) myClassMethod;

The definition also uses the plus sign, but is otherwise identical to an instance method:

+ (void) myClassMethod
{
   printf("In myClassMethod\n");
}

Since you don't use an object instance to call these methods on, you use the class name when calling class methods. For example, if the above class method were part of the Rectangle class, it would be called like this:

   [Rectangle myClassMethod];

Class methods, because they do not require an instance, are very similar to a function call. The benefit is that the are tied to a particular class. Whether you create a function or a class method really depends on the situation. One particular case where class methods are useful is for creating autoreleased instances in a single step.

Because autoreleased objects make memory management easier when you use short-lived objects, they tend to get used a lot. However, creating them can be a bit a pain. For example, to create an autoreleased instance of our Rectangle class, we need to call three methods:

   rectangle = [[Rectangle alloc] initWithLeftX   : 5
                               bottomY   : 5
                                rightX   : 15
                                 topY   : 10];
   [rectangle autorelease];

To make this common task easier, it is useful to create a class method that does this all in one step:

+ (Rectangle *) rectangleWithLeftX   : (float) leftX
                     bottomY   : (float) bottomY
                     rightX   : (float) rightX
                       topY   : (float) topY;
{
   Rectangle * rectangle =
      [[self alloc] initWithLeftX: leftX
                     bottomY   : bottomY
                      rightX   : rightX
                        topY   : topY];
   return [rectangle autorelease];
}

This could then be used like:

   rectangle = [Rectangle rectangleWithLeftX   : 5
                             bottomY   : 5
                              rightX   : 15
                               topY   : 10];

You will see this "class method for autorelease" pattern in many of the standard Foundation and Cocoa libraries. By convention, the name of the class method starts with the name the class. For example, there's an NSNumber class in Foundation that holds standard C numbers, such as int and float. To create an instance of this, you would use:

   NSNumber * number = [[NSNumber alloc] initWithInt: 42];

To create an autoreleased instance, you would use the numberWithInt: class method:

   NSNumber * number = [NSNumber numberWithInt: 42];

I mention this because the pattern is so heavily used that the documentation often fails to mention the fact that the return object is autoreleased. So just keep this in mind if you see code like this and you are wondering why release is not being called on these objects.

Garbage Collection

While reference counting is a big step up from the malloc and free usage of standard C, it can still be problematic, especially since Objective-C uses manual reference counting. It is easy for a programmer to forget to call release and cause memory leaks. Properly using retain and release is yet another thing programmers have to think about, instead of how to implement new features. Thankfully, there exists another technique for dealing with dynamic memory.

Objective-C 2.0, which was released along with Mac OS X 10.5, Leopard, includes a technique called garbage collection. In short, garbage collection, or GC, works by having the system keep track of all object allocations and assignments. Then, the system will periodically scan all allocated objects, looking for objects that have no references to them. If an object has no references, it is considered garbage and deallocated automatically.

In plain English, this means that you no longer have to use retain, release, or autorelease ever again. Memory management is completely automatic, and the burden of memory leaks, dangling pointers, and retain cycles has been lifted from the backs of Objective-C programmers. This is really huge. Here is our RectanglePrinter test application from Listing 4 written with garbage collection:

Listing 8: Garbage collection example

#import <Foundation/Foundation.h>
#import "Rectangle.h"
#import "RectanglePrinter.h"
int main (int argc, const char * argv[])
{
   Rectangle * rectangle;
   
   rectangle = [[Rectangle alloc] initWithLeftX   : 5
                               bottomY   : 5
                                rightX   : 15
                                 topY   : 10];
   
   RectanglePrinter * printer =
      [[RectanglePrinter alloc] init];
   
   [printer setRectangle: rectangle];
   [printer printArea];
   
   return 0;
}

As you can see, we've removed the autorelease pool and all calls to release. Of course, there are still a few finer points you have to worry about, but in general, Apple has delivered on this. Another major difference you will notice is that the dealloc method is no longer called, thus you should not implement it. This is because you no longer need to release your references to other objects. While the lack of dealloc is mainly transparent, there are some cases when you will have to restructure your code a bit. For classes that just release their instance variables, like our RectanglePrinter, it means we can just delete our dealloc method and things will work. We will go over the finer points of GC as we come across them in future articles.

The only major downside at this point is that GC is only supported on Leopard. If you are writing code that needs to execute on prior versions of Mac OS X, you won't be able to use GC, just yet.

Conclusion

Objective-C memory management is a bit different from most other languages out there. Until recently, it used reference counting which is more flexible than malloc and free, but it's not completely automatic. There are a few rules that you must follow in order to properly retain and release objects. This means you must constantly think about and follow the rules in your programs. The advent of Leopard brings us garbage collection and promises to simplify memory management even more. In either case, memory management is a cornerstone of Objective-C programming. With this topic under your belt, we can start exploring areas of the Foundation and Cocoa libraries.


Dave Dribin has been writing professional software for over eleven years. After five years programming embedded C in the telecom industry and a brief stint riding the Internet bubble, he decided to venture out on his own. Since 2001, he has been providing independent consulting services, and in 2006, he founded Bit Maki, Inc. Find out more at http://www.bitmaki.com/ and http://www.dribin.org/dave/.

 
AAPL
$97.67
Apple Inc.
+0.64
MSFT
$44.50
Microsoft Corpora
+0.10
GOOG
$589.02
Google Inc.
-4.33

MacTech Search:
Community Search:

Software Updates via MacUpdate

TinkerTool 5.3 - Expanded preference set...
TinkerTool is an application that gives you access to additional preference settings Apple has built into Mac OS X. This allows to activate hidden features in the operating system and in some of the... Read more
Audio Hijack Pro 2.11.0 - Record and enh...
Audio Hijack Pro drastically changes the way you use audio on your computer, giving you the freedom to listen to audio when you want and how you want. Record and enhance any audio with Audio Hijack... Read more
Intermission 1.1.1 - Pause and rewind li...
Intermission allows you to pause and rewind live audio from any application on your Mac. Intermission will buffer up to 3 hours of audio, allowing users to skip through any assortment of audio... Read more
Autopano Giga 3.6 - Stitch multiple imag...
Autopano Giga allows you to stitch 2, 20, or 2,000 images. Version 3.0 integrates impressive new features that will definitely make you adopt Autopano Pro or Autopano Giga: Choose between 9... Read more
Airfoil 4.8.7 - Send audio from any app...
Airfoil allows you to send any audio to AirPort Express units, Apple TVs, and even other Macs and PCs, all in sync! It's your audio - everywhere. With Airfoil you can take audio from any... Read more
Microsoft Remote Desktop 8.0.8 - Connect...
With Microsoft Remote Desktop, you can connect to a remote PC and your work resources from almost anywhere. Experience the power of Windows with RemoteFX in a Remote Desktop client designed to help... Read more
xACT 2.30 - Audio compression toolkit. (...
xACT stands for X Aaudio Compression Toolkit, an application that encodes and decodes FLAC, SHN, Monkey’s Audio, TTA, Wavpack, and Apple Lossless files. It also can encode these formats to MP3, AAC... Read more
Firefox 31.0 - Fast, safe Web browser. (...
Firefox for Mac offers a fast, safe Web browsing experience. Browse quickly, securely, and effortlessly. With its industry-leading features, Firefox is the choice of Web development professionals... Read more
Little Snitch 3.3.3 - Alerts you to outg...
Little Snitch gives you control over your private outgoing data. Track background activityAs soon as your computer connects to the Internet, applications often have permission to send any... Read more
Thunderbird 31.0 - Email client from Moz...
As of July 2012, Thunderbird has transitioned to a new governance model, with new features being developed by the broader free software and open source community, and security fixes and improvements... Read more

Latest Forum Discussions

See All

Reddme for iPhone - The Reddit Client (...
Reddme for iPhone - The Reddit Client 1.0 Device: iOS iPhone Category: News Price: $.99, Version: 1.0 (iTunes) Description: Reddme for iPhone is an iOS 7-optimized Reddit client that offers a refreshing new way to experience Reddit... | Read more »
Jacob Jones and the Bigfoot Mystery : Ep...
Jacob Jones and the Bigfoot Mystery : Episode 2 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: Jacob Jones is back in Episode 2 of one of Apples 'Best of 2013' games and an App Store... | Read more »
New Trailer For Outcast Odyssey, A New K...
New Trailer For Outcast Odyssey, A New Kind of Card Battler Posted by Jennifer Allen on July 25th, 2014 [ permalink ] Out this Fall is a new kind of card battle game: Outcast Odyssey. | Read more »
Garfield: Survival of the Fattest Coming...
Garfield: Survival of the Fattest Coming to iOS this Fall Posted by Jennifer Allen on July 25th, 2014 [ permalink ] Who loves lasagna? Me. Also everyone’s favorite grumpy fat cat, Garfield. | Read more »
Happy Flock Review
Happy Flock Review By Andrew Fisher on July 25th, 2014 Our Rating: :: HERD IT ALL BEFOREUniversal App - Designed for iPhone and iPad Underneath the gloss of Happy Flock’s visuals is a game of very little substance. It’s cute, but... | Read more »
Square Register Updates Adds Offline Pay...
Square Register Updates Adds Offline Payments Posted by Ellis Spice on July 25th, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Looking For Group – Hearthstone’s Curse...
For the first time since its release (which has thankfully been a much shorter window for iPad players than their PC counterparts), Blizzard’s wildly successful Hearthstone: Heroes of Warcraft CCG is sporting some brand new content: the single... | Read more »
Poptile Review
Poptile Review By Jennifer Allen on July 25th, 2014 Our Rating: :: SIMPLY FUNUniversal App - Designed for iPhone and iPad Simple yet a little bit glorious, Poptile is a satisfying entertaining puzzle game with oodles of the ‘one... | Read more »
Modern Combat 5: Blackout Review
Modern Combat 5: Blackout Review By Brittany Vincent on July 25th, 2014 Our Rating: :: LESS QQ, MORE PEW PEWUniversal App - Designed for iPhone and iPad The fifth entry into the blockbuster Modern Combat series is what mobile... | Read more »
Watch and Share Mobile Gameplay Videos W...
Watch and Share Mobile Gameplay Videos With Kamcord Posted by Jennifer Allen on July 25th, 2014 [ permalink ] iPhone App - Designed for the iPhone, compatible with the iPad | Read more »

Price Scanner via MacPrices.net

iMacs on sale for $150 off MSRP, $250 off for...
Best Buy has iMacs on sale for up to $160 off MSRP for a limited time. Choose free home shipping or free instant local store pickup (if available). Prices are valid for online orders only, in-store... Read more
Mac minis on sale for $100 off MSRP, starting...
Best Buy has Mac minis on sale for $100 off MSRP. Choose free shipping or free instant local store pickup. Prices are for online orders only, in-store prices may vary: 2.5GHz Mac mini: $499.99 2.3GHz... Read more
Global Tablet Market Grows 11% in Q2/14 Notwi...
Worldwide tablet sales grew 11.0 percent year over year in the second quarter of 2014, with shipments reaching 49.3 million units according to preliminary data from the International Data Corporation... Read more
New iPhone 6 Models to Have Staggered Release...
Digitimes’ Cage Chao and Steve Shen report that according to unnamed sources in Apple’s upstream iPhone supply chain, the new 5.5-inch iPhone will be released several months later than the new 4.7-... Read more
New iOS App Helps People Feel Good About thei...
Mobile shoppers looking for big savings at their favorite stores can turn to the Goodshop app, a new iOS app with the latest coupons and deals at more than 5,000 online stores. In addition to being a... Read more
Save on 5th generation refurbished iPod touch...
The Apple Store has Apple Certified Refurbished 5th generation iPod touches available starting at $149. Apple’s one-year warranty is included with each model, and shipping is free. Many, but not all... Read more
What Should Apple’s Next MacBook Priority Be;...
Stabley Times’ Phil Moore says that after expanding its iMac lineup with a new low end model, Apple’s next Mac hardware decision will be how it wants to approach expanding its MacBook lineup as well... Read more
ArtRage For iPhone Painting App Free During C...
ArtRage for iPhone is currently being offered for free (regularly $1.99) during Comic-Con San Diego #SDCC, July 24-27, in celebration of the upcoming ArtRage 4.5 and other 64-bit versions of the... Read more
With The Apple/IBM Alliance, Is The iPad Now...
Almost since the iPad was rolled out in 2010, and especially after Apple made a 128 GB storage configuration available in 2012, there’s been debate over whether the iPad is a serious tool for... Read more
MacBook Airs on sale starting at $799, free s...
B&H Photo has the new 2014 MacBook Airs on sale for up to $100 off MSRP for a limited time. Shipping is free, and B&H charges NY sales tax only. They also include free copies of Parallels... Read more

Jobs Board

*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
Sr Software Lead Engineer, *Apple* Online S...
Sr Software Lead Engineer, Apple Online Store Publishing Systems Keywords: Company: Apple Job Code: E3PCAK8MgYYkw Location (City or ZIP): Santa Clara Status: Full Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.