Posts tagged #xcode 5

iPhone App Memory Management - Why Do I Get Errors About Retain Release Dealloc in Xcode 5

In Xcode 4 and Xcode 5 an underrated developer tool for beginners is called ARC (). It simplifies a lot of the code and logic that we used to need to think about when we wrote apps.

Unfortunately, a lot of the code that you'll find on StackOverflow contains release, retain, autorelease, and [super dealloc]. When you try to copy that code into a new Xcode 5 project you'll get Xcode errors complaining about it. For the most part you can remove the extra nested method call to retain, release, autorelease, and you can delete anything that says [super dealloc].

If you want to see some examples I've posted some snippets of code of what you used to write and how it translates with the ARC code. Older projects should be updated to ARC because it makes it a lot easier to add open-source libraries that use ARC, or ARC code files.

Side note: I wrote before ARC was released and it was a royal pain trying to add some extra source code that was designed for ARC at the last minute before an art exhibit at Joe Bean Coffee Roasters. In the near future I plan on converting my app, Artwork Evolution, to ARC to make it easier to integrate some code that I've been using in my newer apps.

Example Xcode 5 Error Messages

NSDate *date = [[NSDate date] retain];

In non-ARC code we needed to explicitly tell the iPhone that we needed to hold onto memory so that we could do calculations or respond to user input. You'll see a lot of code littered with retain calls to make sure the app doesn't crash.

ARC: In ARC code we can remove all of these retain statements and make the code easier to follow and read. 

'retain' is unavailable: not available in automatic reference counting mode
ARC forbids explicit message send of 'retain'

Rewrite the code as:

NSDate *date = [[NSDate date] retain];  // Non-ARC

NSDate *date = [NSDate date]; // ARC

or

NSDate *date = [[[NSDate alloc] init] retain]; // Non-ARC

NSDate *date = [[NSDate alloc] init]; // ARC

Note: With ARC, both [[NSDate alloc] init] and [NSDate date] behave the same. You can make your code more concise by using the static convenience method [NSDate date].

[image release];

Release was used to let the system know that you were done with memory. This allowed the memory to be used for other programs or other parts of your app. If you forgot to do these calls you ended up with memory leaks, and eventually your app would crash because it didn't have any memory to use.

ARC: In ARC code you can safely remove any calls to release.

'release' is unavailable: not available in automatic reference counting mode
ARC forbids explicit message send of 'release'

// Non-ARC
UIImage *image = [UIImage imageNamed:@"BombDodge.png"];
self.logoImageView.image = image;
[image release];

// ARC
UIImage *image = [UIImage imageNamed:@"BombDodge.png"];
self.logoImageView.image = image;

 

[super dealloc];

In non-ARC code we had to make sure to call the super method of dealloc to finish cleaning up our memory. If you didn't do this and didn't release objects that you were finished using you would have memory leaks.

ARC: In ARC code we don't, so you can safely remove those calls in your classes or sample code you copy/paste from StackOverflow. You can also remove any calls to release or objects set to nil.

ARC forbids explicit message send of 'dealloc'
// Non-ARC
- (void)dealloc {
    [super dealloc];
    
    [image release];
    image = nil;
    
    [self closeNetworkConnection];
}

// ARC
-(void)dealloc {
    [self closeNetworkConnection];
}

ARC: There are two special cases that you may want to keep the dealloc method (if it's empty you don't need it).

  1. If you need to close down a network connection, socket, database, etc. You can use the dealloc method as a hook to trigger that action.
  2. If you set any delegate objects that don't use a "weak" property modifier like the UITableView delegate or dataSource, you may want to set those to nil. You can run into situations with KVO or object lifetime where the class you created doesn't live as long as the UITableView class. In that case the UITableView object might send a message to your deallocated object, which can cause a crash.
// UITableView property is not weak!
@property(nonatomic, assign) id dataSource

// Custom dealloc to nil out the property to prevent crashes
- (void)dealloc {
    self.tableView.dataSource = nil;
    self.tableView.delegate = nil;
}

[myObject autorelease];

A lot of times when we worked with memory management, we used the auto release pools, which allowed us to use memory without having to do retain/release methods. There's a convention to how these methods were named, and your using them when you use something like [NSDate date]. The object will be alive for the scope of where it's used, unless you make an explicit retain call.

FIX: With ARC we don't need to worry about these old conventions and can just remove the extra method call to autorelease.

'autorelease' is unavailable: not available in automatic reference counting mode
ARC forbids explicit message send of 'autorelease'
// Non-ARC
+ (MyObject)myObject {
    MyObject *myObject = [[MyObject alloc] init];
    myObject.title = @"A title";
    myObject.on = NO;
    return [myObject autorelease];
}

// ARC
+ (MyObject)sampleObject {
    MyObject *myObject = [[MyObject alloc] init];
    myObject.title = @"A title";
    myObject.on = NO;
    return myObject;
}

Conclusion

When you copy/paste code from old textbooks or StackOverflow you may have to clean up the code to get it to work in the latest versions of Xcode 4 or Xcode 5+.

ARC is Automatic Reference Counting and it saves you a lot of time thinking about who "owns" a piece of memory (to store images, text, numbers, etc) in your apps. You can instead focus on how the logic of the app will work, how it will save data, how it will transition between screens, how it will animate and help the user accomplish a task.

Posted on May 30, 2014 and filed under Programming .

Auto Layout Bug with the Top Layout Guide for Xcode 5

Update (3/14/14): Xcode 5.1 fixes this bug. When you drag to the top it'll add the appropriate top constraint and won't send your views offscreen or offset them incorrectly.

I do a lot of UI work in Xcode 5 with Interface Builder. I'm building class materials and this is a very common bug, that I didn't figure out a good solution until now. These types of bugs can make Auto Layout very frustrating to learn because it doesn't behave like you might expect. I'll describe the bug below, the solution, and a video solution for the curious.

Top Layout Guide Bug

If you add a view to a .storyboard or .xib file, you can align it to the top edge or just under the status bar. This edge under the status bar in Xcode 5 is called the Top Layout Guide. The guide is a helper for setting up constraints, but unfortunately it doesn't work as you might expect most of the time.

When you Right-click + Drag (Ctrl + Left-click + Drag) to add constraints to the Top Layout Guide it'll add the wrong constraint and your iPhone app layout will not be what you expect.

The layout doesn't match what we would expect. Label is squashing our status bar text!

The layout doesn't match what we would expect. Label is squashing our status bar text!

Instead of adding a constraint from the top of the view to the Top Layout Guide, it adds a constraint from the bottom of the view to the Top Layout Guide. For some reason this creates a constraint that pushes your view upwards and it conflicts with the status bar, or it'll go above the status bar.

Solution

The work around is to use the Menu bar options to add the constraint using the Pin menu. You can't add the constraints with the Right-click + Drag menu. Note: Delete any previous constraints to the Top Layout Guide, or the steps below won't help.

Editor > Pin > Top Space to Superview

Pin the Top Space to the Superview and you'll fix your bug.

Pin the Top Space to the Superview and you'll fix your bug.

After we add the Pin to the superview, we'll have to add all the normal constraints. You should see the following constraints (visually) if you look at the top view.

Correct Auto Layout Constraints for the Top Layout Guide

Correct Auto Layout Constraints for the Top Layout Guide

4 Layout Constraints to specify the size and position 

4 Layout Constraints to specify the size and position 

Using the new layout, the label will appear on the iPhone Simulator in the correct spot, and so will the red UIView. Now using this powerful tip you can make your app match your design.

Proper Auto Layout for a UIView that is near the top of an iPhone.

Proper Auto Layout for a UIView that is near the top of an iPhone.

 

Solution Video

","url":"http://www.youtube.com/watch?v=lxc9DnqpI0c","width":854,"height":480,"providerName":"YouTube","thumbnailUrl":"http://i1.ytimg.com/vi/lxc9DnqpI0c/hqdefault.jpg","resolvedBy":"youtube"}" data-block-type="32" id="block-e079ff8611a3fdb3a351">
Posted on March 6, 2014 and filed under Programming .