TweetFollow Us on Twitter

The Road to Code: Quit Bugging Me

Volume Number: 25 (2009)
Issue Number: 02
Column Tag: The Road to Code

The Road to Code: Quit Bugging Me

Debugging on Mac OS X

by Dave Dribin

The Perfect Story

You've been a faithful reader of The Road to Code. You've typed in every code example to gain complete understanding. If you had problems getting something working, you could always download the source code from the MacTech web site. But now, you're off on your own. You've started writing your own applications, and inevitably, something goes wrong. Your application doesn't work as you expect it. Or it crashes, losing all your hard-entered data. How do you figure out what's going wrong?

The process of fixing an application that does not work correctly is called debugging. The term debugging in the context of computer software is often credited to an early computer scientist named Grace Hopper. As the legend goes, she was working on the Mark II system at Harvard, investigating a glitch in the system. The problem ended up being a moth stuck in one of the relays, and she dubbed this the "first actual case of bug being found". From then on, whenever a computer system has not worked, it is blamed on bugs. Thus, removing bugs in a computer program is called debugging.

That's a fine and dandy story, but how do you actually debug a program? It's not as if you will usually find real moths stuck inside your computer to eradicate. Let's go over some techniques that you can use to help you debug your own code.

Simple Logging

One of the simplest debugging techniques is to use logging. Say some variable is not being set correctly, and you do not know why. You can begin tracking down the problem by inserting NSLog statements to print its value out to the console. You can even use NSLog in a GUI application and then view the output in the Xcode console. This kind of debugging, while primitive, is surprisingly effective. It's also one of the easiest to implement, since printing to the console is one of the first things you learn how to do.

Sometimes this kind of debugging is called printf debugging, because in straight C you use the printf function instead of NSLog. Using NSLog in Objective-C has some nice advantages, but the main one is the %@ format pattern to print objects. You can use the %@ format string to print any Objective-C object. For example, to print an NSString variable:

    NSString * name = @"Joe";
    NSLog(@"name: %@", name);

You've seen code like this before. The %@ in the format string gets substituted with the string value:

2008-12-07 22:49:09.356 Rectangles[60874:10b] name: Joe

Along with the message you pass as its arguments, NSLog prints the application name and a timestamp. We've seen how you can use other format patterns, such as %d to print integers and %f to print floating point numbers. The %@ formatter works on any class, not just NSString though. Here's how you could print an NSNumber instance:

    NSNumber * number = [NSNumber numberWithInt:42];
    NSLog(@"number: %@", number);

The output would look like this:

number: 42

I'm omitting the timestamp and application name from now on, to keep the output succinct, but there's nothing too surprising going on here. You get useful output on a surprising number of classes included in Foundation and AppKit. For example, logging an NSArray instance displays the contents of the array:

    NSArray * array =
       [NSArray arrayWithObjects:@"Jack", @"Jane", nil];
    NSLog(@"array: %@", array);

The output would look like this:

array: (
    Jack,
    Jane
)

You can even use %@ on your own objects; however, it doesn't always provide useful information. Let's use the Rectangles application from the October 2008 issue, as an example. You can get it from the MacTech FTP site, if you need to. Here's how you could log one of our Rectangle objects:

    Rectangle * rectangle =
        [[Rectangle alloc]   initWithLeftX:0
                                 bottomY:0
                                  rightX:15
                                    topY:10];
    NSLog(@"rectangle: %@", rectangle);

And here's what it looks like by default:

rectangle: <Rectangle: 0x104fba0>

Hrm... not very useful. It's printing out the pointer value of the object. Luckily, we can customize this output. In order to turn an object into a string, NSLog uses the description method defined on NSObject. The default implementation prints the class name and the pointer value of self, and it would look something like this:

- (NSString *)description
{
    NSString * description =
        [NSString stringWithFormat:@"<%@: %p>", [self className], self];
    return description;
}

It's using the className method, also defined on NSObject, to get the name of the class as a string. The %p format specifier prints out pointer values. The output is the hexadecimal number of the memory address of the pointer.

By overriding description in our Rectangle class, we can give it more meaningful output. As a refresher, Listing 1 shows the interface for the Rectangle class.

Listing 1: Rectangle.h header file

#import <Foundation/Foundation.h>
@interface Rectangle : NSObject <NSCoding>
{
    float _leftX;
    float _bottomY;
    float _width;
    float _height;
}
@property float leftX;
@property float bottomY;
@property float width;
@property float height;
@property (readonly) float area;
@property (readonly) float perimeter;
- (id) initWithLeftX:(float)leftX
            bottomY:(float)bottomY
             rightX:(float)rightX
               topY:(float)topY;
@end

A useful implementation of description would output the leftX, bottomY, width, and height:

- (NSString *)description
{
    NSString * description =
        [NSString stringWithFormat:
         @"<%@: (%.1f, %.1f) %.1f x %.1f>",
         [self className],
         _leftX, _bottomY, _width, _height];
    return description;
}

Now, when we log our rectangle variable above, it would look like this:

rectangle: <Rectangle: (0.0, 0.0) 15.0 x 10.0>

Ah! Much better. We can now use logging to dump our rectangles out to the console.

There are, of course, downsides to using logging for debugging. If you need to view a large number of variables or watch a variable change from line to line, you'll need to insert lots of logging statements. This is tedious and takes time. You also may accidentally leave your debug logging statements inside a shipping application. This can clutter up the user's console and even affect the performance of your application, so it is not a good idea to have NSLog statements in a released application. Don't fret. There's something better called a debugger.

Xcode Debugger

A debugger is an application whose purpose is to help debug another application. The main feature of a debugger is the ability to set breakpoints. Breakpoints allow you to stop the execution of a running application and investigate the state of the application. You can typically examine any local variables, instance variables, and global variables from within a debugger.

Xcode comes with an integrated debugger, meaning that you can use Xcode to set breakpoints. The simplest way to explain how it works is to provide an example. Take this code that is the constructor for the Rectangle class:

- (id) initWithLeftX:(float)leftX
            bottomY:(float)bottomY
             rightX:(float)rightX
               topY:(float)topY
{
    self = [super init];
    if (self == nil)
        return nil;
    
    _leftX = leftX;
    _bottomY = bottomY;
    _width = rightX - leftX;
    _height = topY - bottomY;
    
    return self;
}

Say we want to see if the rectangle is created properly. You simply click on the left margin with the line numbers, and a blue arrow is added to indicate that you added a breakpoint, as in Figure 1.


Figure 1: Setting a breakpoint in Xcode

To trigger the breakpoint, we first need to run our application with the debugger instead of running it normally. You do this by choosing the Build > Build and Debug menu, or Command-Y, instead of the usual Build > Build and Run menu, or Command-R. This will launch your application, but whenever code that has a breakpoint set is executed, the program stops execution. In order to trigger our example breakpoint, you need to hit the Add button in the user interface, which ends up creating a new rectangle.

When you do this, the debugger will stop your program, and Xcode will change the main editor interface to show you that you have stopped at a breakpoint, as shown in Figure 2. You can see that it adds a red arrow in the left margin and it highlights the line that the red arrow is on in blue. This is done to clearly indicate where the debugger has halted your application.Debugger integration within the standard editing window is new to Xcode 3. There is also a separate debugging window, which contains more debugging information. You can view this window by choosing the Run > Debugger menu, which looks like Figure 3.


Figure 2: Xcode stopped at a breakpoint


Figure 3: Xcode debugger window

While your program is halted, you can poke around and investigate its state. The lower pane of the debugger window is similar to the main editor window in that it shows you your code, along with the red arrow and blue highlight to indicate where you application stopped. The upper left pane of the debugger window shows the method call stack, or stack trace. This shows all method calls that lead you to this point, all the way back to main function that started the application.

The upper right pane of the debugger window allows you to examine the value of any variable. Variables that contain other variables, such as structures or objects, have a little disclosure triangle. Clicking on the triangle displays the containing variables. For example, clicking on the triangle of the self variable allows us to examine the instance variables, as shown in Figure 4. As you can see, all instance variables are set to zero initially.


Figure 4: Examining variables

Examining variables is extremely helpful when trying to figure out how your application is misbehaving, but there is a lot more you can do with a debugger. Most likely, you are going to want to start your application up again. There are two ways to resume execution of your program: continuing and stepping. Continuing starts the application back up again, and it will resume as if nothing happened.

Stepping allows you to continue execution temporarily and execute the statements of your program one at a time. By stepping through your program, you can watch how each statement modifies variables. Say we step over the four statements that assign the instance variables. The debugger window would now look like Figure 5.


Figure 5: Stepping over statements

You will notice that the red arrow and blue highlight move as each statement is executed. Also the variable examination pane highlights variables that have changed in red. Thus, the _height instance variable is red because we just assigned to it. You can keep stepping as long as you would like and watch your application execute in slow motion.

There are actually two kinds of stepping: step into and step over. Both continue execution temporarily, but the difference is how the debugger handles method and function calls. Using "step into" the debugger will follow execution into method and function calls and stop at the first statement inside the called method. "Step over" will not follow execution into method and functions calls, and instead will stop on the next line of the current method. If the statement is not a method or function call, then "step into" and "step over" are equivalent.

The toolbar of the debugger window has buttons labeled Continue, Step Over, and Step Into so you can easily restart your application using one of these commands. It's worth noting that you can only step into your own code. Any code that is part of the system frameworks cannot be stepped into.

The upper left pane that shows the method call stack allows you to "back up" the method call chain and view the state of each method, too. By default, the top of the stack is selected. For example, if I click on the second method in the stack, -[MyDocument addRectangle:], the debug window would change to look like Figure 6. Again, you can only select method calls that are in your code. You cannot select methods that are part of the system frameworks, and they are grayed out.


Figure 6: Selected methods in the call stack

The source pane and the variable pane update to the new method when you click on one. Thus, the variable arguments and locals shown in Figure 6 are for the addRectangle: method.

Debugger Console

There's another important part of Xcode's debugger called the debugger console. This is the same console where logging output usually goes, but with the debugger active, it's turned into a command line interface for the debugger.

Xcode's debugger is built around a debugger called gdb, the GNU debugger. gdb is traditionally run from the command line to debug C and C++ programs. Xcode wraps most of gdb's functionality with an easy to use GUI, but the console allows you to enter commands directly to gdb. The print command, for example, prints the value of a variable. You can use this instead of the variable pane in the GUI to examine variables. You can examine the rightX local variable from the console like this:

(gdb) print rightX
$4 = 15

The print command only works on primitive types, though. If you want to examine Objective-C objects, you need to use the print-object command. It uses the same description method that NSLog uses to get the string value of an object, so if we used this on self at the end of the Rectangle constructor, the output would look like this:

(gdb) print-object self
<Rectangle: (0.0, 0.0) 15.0 x 10.0>

You can also use po as a shortcut for print-object:

(gdb) po self
<Rectangle: (0.0, 0.0) 15.0 x 10.0>

The arguments to the print and po commands are not limited to printing variables. You can traverse structures and even call Objective-C methods. To call methods, you use the standard square bracket syntax you normally use. Here's how you would print the class name of self:

(gdb) po [self className]
Rectangle

Note that the debugger does not understand property dot notation. You have to use the square bracket syntax:

(gdb) print self.area
There is no member named area.
(gdb) print [self area]
$6 = 150

Generally print is smart enough to figure out the type to print out, but sometimes you need to give it a hint. If you need to do this, you can use standard C cast syntax to force the value to be a certain type:

(gdb) print (int)[self area]
$7 = 150

The command line is powerful, yet complex. Everything available in the Xcode debugger GUI is available from the gdb console. For example, the commands that correspond to the Continue, Step Over, and Step Into of the GUI are continue, next, and step, respectively.

Breakpoint Actions

One use for gdb commands is to assign actions to breakpoints. Instead of breakpoints stopping the program and not continuing right away, you can add actions to breakpoints. These actions are executed automatically when the breakpoint is triggered. Actions can be gdb commands, log statements, or even AppleScripts.

Xcode has some pre-configured breakpoint actions that you can use when setting a breakpoint. The easiest way to access these is to right click (or Control click) in the left margin of the source editor, and choose Built-in Breakpoints from the contextual menu, as shown in Figure 7.


Figure 7: Built-in Breakpoints

Let's choose Print self and auto-continue to see how it works. Now, when we run our program and cause the breakpoint to trigger, it will log the description of the Rectangle and continue. This is just like adding an NSLog statement, except you do not have to modify your code!

Let's see how this works behind the scenes. Right click on the blue breakpoint arrow in the left margin and choose Edit Breakpoint from the contextual menu. This will bring up the Breakpoints window as shown in Figure 8. Alternatively, you can access this window from the Breakpoints toolbar item or the Run > Show > Breakpoints menu.


Figure 8: Breakpoint with an action

This window shows that the po self debugger command is automatically executed when the breakpoint is hit. Also, the rightmost column is checked, meaning the application is automatically continued. This combination is how you can add logging statements without modifying the code. Again, you can use any gdb command you can type at the console as an action, so breakpoint actions are very powerful.

Debugging Crashes

While breakpoints are a great way to track down bugs, sometimes your application will unexpectedly crash, and you don't know where to start looking. The debugger can help in these cases, too. Crashes can happen for many reasons, but one of the most common is dereferencing a NULL pointer. In order to demonstrate this point, I'm going to make the program crash by inserting a bug.

- (IBAction)addRectange:(id)sender
{
    // Dereference a NULL pointer
    int * pointer = NULL;
    *pointer = 0;
    Rectangle * rectangle =
        [[Rectangle alloc]   initWithLeftX:0
                                 bottomY:0
                                  rightX:15
                                    topY:10];
    
    [_rectangles addObject:rectangle];
    
    // Update the UI
    [_tableView reloadData];
    [self updateTotalAreaAndPerimeter];
}

The second line in the method will cause the application to crash when executed. To trigger this bug, all you have to do is click on the Add button in the GUI. If you try this, you'll notice that Xcode will catch the crash and automatically attach the debugger. The debugger will then highlight the exact line where the crash occurred, with the red arrow and blue highlight, as shown in Figure 9. You can now examine the state of your application to figure out why the crash occurred. In this case, it's obvious: pointer is 0x0, or NULL. However, it may not be obvious in a real crash. The debugger gives you a chance to investigate what caused the crash.


Figure 9: Xcode debugger catching a crash

The debugger will only get attached to a crashing program when running within Xcode. If a program crashes outside of Xcode, you will get a standard dialog, as shown in Figure 10.


Figure 10: Application crash dialog

There's not much information here to help you debug. However, ever time any application crashes, Mac OS X saves what's called a crash log. Crash logs contain information that may help determine why an application crashed, and they are stored in this directory:

~/Library/Logs/CrashReporter/

There's one text file per crash, and if you open up one of these files, you'll see the full crash log. The most useful part of the crash log is what's known as a stack trace. This is similar to the upper left pane of the debugger, in that it shows you the methods called in the current stack before the crash occured. The first line of the crash log (which I've edited for brevity) will look something like this:

Thread 0 Crashed:
0  [...] -[MyDocument addRectange:] + 29 (MyDocument.m:64)
1  [...] -[NSApplication sendAction:to:from:] + 112
[...]
11 [...] 0x00002679 main + 30 (main.m:14)
12 [...] start + 54

It tells us exactly which line our program crashed on. While your program has already exited, and you can't examine it for more information, the crash log is often very helpful in determining why your application crashed for a user.

You can actually configure the crash window to give you crash logs, as well, using the CrashReporterPrefs application, found in this directory:

/Developer/Applications/Utilities/

CrashReporterPrefs allows you to configure Crash Reporter for Developer mode. When in Developer mode, you can view crash logs right in the GUI when the application crashes, as shown in Figure 11. However, you get this crash dialog whenever any application crashes, not just ones you've written, so you may find this behavior too annoying to leave Developer mode on by default.


Figure 11: Crash dialog in Developer mode

Xcode Configurations

Take a look in the Xcode toolbar, and you'll notice the Overview item in the toolbar on the left hand side. It should say something like 10.5 | Debug | i386. To know what this means, click on the toolbar item, and you'll see a menu similar to Figure 12. You'll see that 10.5 corresponds to the Active SDK, Debug corresponds to the Active Configuration, and i386 corresponds to the Active Architecture. A full description of all these items is beyond the scope of this article, but we're going to briefly talk about the Active Configuration and Active Architecture settings.


Figure 12: Xcode overview menu

By default, Xcode uses the Debug configuration. You'll notice there is also a Release configuration. This is because your application needs to be compiled in a special manner to work properly with the debugger. When you compile with the Release configuration, your application will be faster and use less disk space, so you will want to use it before distributing your application to your users. However, it may not work well with the debugger. You may have trouble setting breakpoints, and the stack traces included when your application crashes may not be as accurate. For example, it may not be able to tell you exactly which line your application crashed on.

Also, in the Debug configuration, your application is only compiled for the Active Architecture, which speeds up compile times. In contrast, the Release configuration will compile your application as a Universal binary and will run natively on both PowerPC and Intel Macs. However, this means your code is compiled twice and can slow down development time.

The Active Architecture is the architecture of your current hardware: if you are running on an Intel Mac, the architecture will be set to i386. If you're on a PowerPC Mac, the architecture will be set to ppc. This means that your application will only run natively on the same type of Mac that you have.

Because of the differences between Debug and Release configurations, you will typically use Debug while developing your application and Release to build the final version you ship to your users. Just be aware that you will not be able to accurately debug that final version or get accurate stack traces if your application crashes.

Conclusion

This article has given you a brief overview of how to use logging and Xcode's integrated debugger to help you diagnose and fix errors in your programs. Debugging is an art in and of itself, and just like programming, the more you do it, the better you get at it. There are lots of resources on the Internet about debugging in general as well as specifics on how to use gdb and the Xcode debugger. For instance, Apple has a good article called "Technical Note TN2124: Mac OS X Debugging Magic" on their website. This article is chock full of tips and tricks of debugging techniques for Mac OS X and a worthy read.

Bibliography

"Technical Note TN2124" http://developer.apple.com/technotes/tn2004/tn2124.html


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
$501.11
Apple Inc.
+2.43
MSFT
$34.64
Microsoft Corpora
+0.15
GOOG
$898.03
Google Inc.
+16.02

MacTech Search:
Community Search:

Software Updates via MacUpdate

Paperless 2.3.1 - Digital documents mana...
Paperless is a digital documents manager. Remember when everyone talked about how we would soon be a paperless society? Now it seems like we use paper more than ever. Let's face it - we need and we... Read more
Apple HP Printer Drivers 2.16.1 - For OS...
Apple HP Printer Drivers includes the latest HP printing and scanning software for Mac OS X 10.6, 10.7 and 10.8. For information about supported printer models, see this page.Version 2.16.1: This... Read more
Yep 3.5.1 - Organize and manage all your...
Yep is a document organization and management tool. Like iTunes for music or iPhoto for photos, Yep lets you search and view your documents in a comfortable interface, while offering the ability to... Read more
Apple Canon Laser Printer Drivers 2.11 -...
Apple Canon Laser Printer Drivers is the latest Canon Laser printing and scanning software for Mac OS X 10.6, 10.7 and 10.8. For information about supported printer models, see this page.Version 2.11... Read more
Apple Java for Mac OS X 10.6 Update 17 -...
Apple Java for Mac OS X 10.6 delivers improved security, reliability, and compatibility by updating Java SE 6.Version Update 17: Java for Mac OS X 10.6 Update 17 delivers improved security,... Read more
Arq 3.3 - Online backup (requires Amazon...
Arq is online backup for the Mac using Amazon S3 and Amazon Glacier. It backs-up and faithfully restores all the special metadata of Mac files that other products don't, including resource forks,... Read more
Apple Java 2013-005 - For OS X 10.7 and...
Apple Java for OS X 2013-005 delivers improved security, reliability, and compatibility by updating Java SE 6 to 1.6.0_65. On systems that have not already installed Java for OS X 2012-006, this... Read more
DEVONthink Pro 2.7 - Knowledge base, inf...
Save 10% with our exclusive coupon code: MACUPDATE10 DEVONthink Pro is your essential assistant for today's world, where almost everything is digital. From shopping receipts to important research... Read more
VirtualBox 4.3.0 - x86 virtualization so...
VirtualBox is a family of powerful x86 virtualization products for enterprise as well as home use. Not only is VirtualBox an extremely feature rich, high performance product for enterprise customers... Read more
Merlin 2.9.2 - Project management softwa...
Merlin is the only native network-based collaborative Project Management solution for Mac OS X. This version offers many features propelling Merlin to the top of Mac OS X professional project... Read more

Briquid Gets Updated with New Undo Butto...
Briquid Gets Updated with New Undo Button, Achievements, and Leaderboards, on Sale for $0.99 Posted by Andrew Stevens on October 16th, 2013 [ | Read more »
Halloween – iLovecraft Brings Frightenin...
Halloween – iLovecraft Brings Frightening Stories From Author H.P. | Read more »
The Blockheads Creator David Frampton Gi...
The Blockheads Creator David Frampton Gives a Postmortem on the Creation Process of the Game Posted by Andrew Stevens on October 16th, 2013 [ permalink ] Hey, a | Read more »
Sorcery! Enhances the Gameplay in Latest...
Sorcery! | Read more »
It Came From Australia: Tiny Death Star
NimbleBit and Disney have teamed up to make Star Wars: Tiny Death Star, a Star Wars take on Tiny Tower. Right now, the game is in testing in Australia (you will never find a more wretched hive of scum and villainy) but we were able to sneak past... | Read more »
FIST OF AWESOME Review
FIST OF AWESOME Review By Rob Rich on October 16th, 2013 Our Rating: :: TALK TO THE FISTUniversal App - Designed for iPhone and iPad A totalitarian society of bears is only the tip of the iceberg in this throwback brawler.   | Read more »
PROVERBidioms Paints English Sayings in...
PROVERBidioms Paints English Sayings in a Picture for Users to Find Posted by Andrew Stevens on October 16th, 2013 [ permalink ] | Read more »
OmniFocus 2 for iPhone Review
OmniFocus 2 for iPhone Review By Carter Dotson on October 16th, 2013 Our Rating: :: OMNIPOTENTiPhone App - Designed for the iPhone, compatible with the iPad OmniFocus 2 for iPhone is a task management app for people who absolutely... | Read more »
Ingress – Google’s Augmented-Reality Gam...
Ingress – Google’s Augmented-Reality Game to Make its Way to iOS Next Year Posted by Andrew Stevens on October 16th, 2013 [ permalink ] | Read more »
CSR Classics is Full of Ridiculously Pre...
CSR Classics is Full of Ridiculously Pretty Classic Automobiles Posted by Rob Rich on October 16th, 2013 [ permalink ] | Read more »

Price Scanner via MacPrices.net

Apple Store Canada offers refurbished 11-inch...
 The Apple Store Canada has Apple Certified Refurbished 2013 11″ MacBook Airs available starting at CDN$ 849. Save up to $180 off the cost of new models. An Apple one-year warranty is included with... Read more
Updated MacBook Price Trackers
We’ve updated our MacBook Price Trackers with the latest information on prices, bundles, and availability on MacBook Airs, MacBook Pros, and the MacBook Pros with Retina Displays from Apple’s... Read more
13-inch Retina MacBook Pros on sale for up to...
B&H Photo has the 13″ 2.5GHz Retina MacBook Pro on sale for $1399 including free shipping. Their price is $100 off MSRP. They have the 13″ 2.6GHz Retina MacBook Pro on sale for $1580 which is $... Read more
AppleCare Protection Plans on sale for up to...
B&H Photo has 3-Year AppleCare Warranties on sale for up to $105 off MSRP including free shipping plus NY sales tax only: - Mac Laptops 15″ and Above: $244 $105 off MSRP - Mac Laptops 13″ and... Read more
Apple’s 64-bit A7 Processor: One Step Closer...
PC Pro’s Darien Graham-Smith reported that Canonical founder and Ubuntu Linux creator Mark Shuttleworth believes Apple intends to follow Ubuntu’s lead and merge its desktop and mobile operating... Read more
MacBook Pro First, Followed By iPad At The En...
French site Info MacG’s Florian Innocente says he has received availability dates and order of arrival for the next MacBook Pro and the iPad from the same contact who had warned hom of the arrival of... Read more
Chart: iPad Value Decline From NextWorth
With every announcement of a new Apple device, serial upgraders begin selling off their previous models – driving down the resale value. So, with the Oct. 22 Apple announcement date approaching,... Read more
SOASTA Survey: What App Do You Check First in...
SOASTA Inc., the leader in cloud and mobile testing announced the results of its recent survey showing which mobile apps are popular with smartphone owners in major American markets. SOASTA’s survey... Read more
Apple, Samsung Reportedly Both Developing 12-...
Digitimes’ Aaron Lee and Joseph Tsai report that Apple and Samsung Electronics are said to both be planning to release 12-inch tablets, and that Apple is currently cooperating with Quanta Computer on... Read more
Apple’s 2011 MacBook Pro Lineup Suffering Fro...
Appleinsider’s Shane Cole says that owners of early-2011 15-inch and 17-inch MacBook Pros are reporting issues with those models’ discrete AMD graphics processors, which in some cases results in the... Read more

Jobs Board

Senior Mac / *Apple* Systems Engineer - 318...
318 Inc, a top provider of Apple solutions is seeking a new Senior Apple Systems Engineer to be based out of our Santa Monica, California location. We are a Read more
*Apple* Retail - Manager - Apple Inc. (Unite...
Job Summary Keeping an Apple Store thriving requires a diverse set of leadership skills, and as a Manager, you’re a master of them all. In the store’s fast-paced, Read more
*Apple* Solutions Consultant - Apple (United...
**Job Summary** Apple Solutions Consultant (ASC) - Retail Representatives Apple Solutions Consultants are trained by Apple on selling Apple -branded products Read more
Associate *Apple* Solutions Consultant - Ap...
**Job Summary** The Associate ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The Associate ASC's role is to 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.