What to watch out for when transitioning to iOS 5 - ios

Summary: Can you add to my checklist of things to watch out for when migrating to iOS 5? StackOverflow has been invaluable as I've worked on upgrading to iOS 5. I've discovered some pretty basic things I'd missed prior to Xcode 4.2, and I'm wondering what other "gotchas" might be lurking.
Detail: With iOS 5 shipping this week, I've had to make some changes to a couple of my apps. Xcode 4.2 does a much better job analyzing memory management code because of the new ARC feature. The iOS 5 update is a great point at which to review all your memory management code. The new compiler also finds a number of other issues that earlier compilers missed. Kudos to the Apple compiler engineers. Here are the main things that have helped (and many of them will also apply to earlier versions of iOS).
Make sure to call [super dealloc] at the END of your dealloc methods, not the beginning.
In viewDidUnload, some people have reported bugs that require [super viewDidUnload] to be called at the end, not the beginning, of your viewDidUnload.
Understand retain counts, synthesized setters, and when to call release or autorelease. The new compiler will point out more problems than the older compilers did. (I thought I'd been careful, but apparently I wasn't careful enough.) Apple's memory management guide is required reading -- no shortcuts.
It's a good idea to turn on zombies when debugging (in Xcode, choose Product | Edit Scheme... and select the Debug scheme; on the Diagnostics tab, check Enable Zombie Objects). This can help you find attempted uses of zombies (objects you shouldn't be using any more).
The Leaks instrument is also helpful. Run your app in Profile mode and choose the Leaks template. In the Instruments window, select the Leaks instrument and check the box that says "Gather Leaked Memory Contents" and it will help you see where the leaked memory originates in your code.
There are a few odds and ends I've encountered:
Apple's singleton pattern needs "oneway" added to the return type declaration:
- (oneway void) release { }
You may need to manually add "armv6" as an architecture type in your Build Settings (and be sure Build Active Architecture Only is set to NO).
Any other suggestions of potential pitfalls I should look for? I have a feeling that my apps are more stable now, but I felt pretty good about them before.

1/ Modal controllers behave differently, if you were changing their size. If you need modal dialog of a different size, consider using iOS 5 child view controllers.
2/ For a table, if you were returning nil section header and positive height, in iOS 4, the header was hidden. In iOS 5, you have to return zero height for nil headers.
3/ UDID is deprecated. You can use CFUUIDCreate to create a unique id and save it into your settings but be aware that a device data can be backed up and then restored to another device, leaving you with two devices with the same id. I solved the situation by saving my id into keychain with attribute kSecAttrAccessibleWhenUnlockedThisDeviceOnly.
About your list:
[super viewDidUnload] should be always called as the last statement in your viewDidUnload. The logic is the same as in [super dealloc]. Note, that you should also call [self viewDidUnload] in your dealloc (if you don't already release your memory there) because it is not called implicitly (although sometimes it is).
From my experiments, leak detection in Instruments don't report leaks on properties which are synthesized without assigning a property name.

Related

IOS/Objective-C: Removing NSLog statements for Release and Build Settings in 2018

A lot of tutorials and answers on SO from the 2008 to 2013 eras say you should remove NSLog statements before releasing an app on the Apple store due to the high overhead of NSLog.
However, by default, Apple seems to have two build configurations, Debug and Release and when you archive the app for release, it now seems to automatically assign the Release configuration.
My question is, in light of this, do you still need to remove the NSLogs or does the Release configuration now automatically do this for you?
Many of the previous answers suggest making an entry in the pch file which no longer exists by default. If you use an alternative debugger apparently you are supposed to make an entry in the Preprocessor Macros however this is beyond my level of knoweldge.
Can anyone shed some light on the preferred approach to the NSLog issue today.

Compilation differences between iOS target 5 and iOS target 6

My iOS App was written with the iOS 5 SDK. the iOS target version of 5 was never modified when I switched to newer version of the SDKs as required by apple.
with the new SDK (9) I can't get it to compile with the old setting and i'm attempting to switch over to a newer target. (6,7,8,9, I get the same issues). the app has mixed code, some files use ARC and some don't. when i switch to newer OS target I get many errors regarding ARC, mostly around dispatch queue management (dispatch_retain/dispatch_release). if i add the -fno-objc-arc the app crashes, if i remove the dispatch_retain/release calls the app crashes. my questions are:
Does anyone knows what was changed in the SDK compilation regrading ARC between iOS 5 and 6?
Any recommendations how to move forward? is there a way to keep arc enabled but tell the compiler to allow manual handling of the dispatch queues?
Nothing significant.
You have to manage queues manually anyway. The only way that ARC interacts with dispatch_* is when you use a block. It's likely that this has always been a problem and that optimisations in the new compiler expose it.
Without seeing the code it's difficult to make any specific recommendations. In general, I tend to set up a queue when the app launches and never deallocate it. trying to find the right times to retain/release a queue just feels like a problem that I don't need to deal with.

Where is xcode instruments "Track Allocations"

In previous versions of instruments, there was a little 'i' button in the allocations tool which allowed you to do things like enable 'track allocations', which allowed you to get object counts of referrers who had currently or historically either retained or released the object - I think even for ARC. I'm currently using 6.3 and I cannot find this functionality at all. Has this been removed from the instrument?
Apple moved the instrument configuration information you would access with the Info button to the lower right area of the trace document window in Xcode 6.

#synthesize of 'weak' property is only allowed in ARC or GC mode with first compile of urbanship

Basically, I have an IOS app that functioned without issue.
While following the instructions at http://docs.urbanairship.com/build/ios.html#ios-push-getting-started, I reached the "Register Your Device" section asking me to compile.
After attempting to build the code in xCode 5 I received the following error "#implementation UAPushSettingsAddTagViewController #synthesize of 'weak' property is only allowed in ARC or GC mode".
Note:ARC mode is not in use.
Search for "weak" in your project code and the libraries you include. Change it to a "assign"
Edit:
As #TaylorHalliday points out in his comment below, my answer was rather incomplete.
Changing weak properties to assign will get rid of compiler errors, but it will potentially cause memory management problems if you don't understand how to use manual reference counting.
Since you're using manual reference counting you will need to go through your code and make sure that you retain objects that you need to persist, and then release all owning references to objects when you are done with them. Explaining the details is beyond the scope of a forum post. I suggest you search on "About Memory Management" in the Xcode help system, and read the entire Advanced Memory Management Guide.
You should probably also run the Analyze tool on your project to look for possible memory management problems.
Better yet, convert your project to use ARC. It's much easier to avoid memory management problems when using ARC.
I got same error when I added these two files to my project. My project wasn't enabled for ARC. I had to remove these files first and then had to convert my project to ARC. Then adding these files caused no error.

ARC conversion tool issues: flagged retain/release, and random parse errors

I'm revisiting an an older project and converting to ARC, my first time through Xcode's conversion tool (Edit -> Refactor -> Convert to Objective-C ARC...), and I'm seeing a couple things that I'm not sure are real issues or red herrings somehow.
I get, as expected a big list of things that the tool finds that prevent it from completing, but:
Many (all?) instances of retain/release/autorelease appear to be flagged as errors e.g. "release is unavailable: not available in automatic reference counting mode". Am I really supposed to get rid of all these myself? I thought that's what the tool did.
In many of my classes, I'm seeing a bunch of errors that look like phantom parse/build errors that have nothing to do with ARC. E.g. in a simple class that apparently has no ARC-related issues, I'll get an "undeclared identifier" on some arbitrary method implementation, and then a bunch of "Parse error: expected }" at the end of the file, etc. These are not real-- the project builds fine, and I don't see any proximate cause or resolution for the errors.
There are "real" issues in the list as well (expected bridging issues that need to be explicitly clarified in code) but there are so many random errors of the above variety that it's hard to even find the signal in the noise. This seems wrong to me.
Am I misunderstanding what this tool is really doing? Apple's docs say this:
Xcode provides a tool that automates the mechanical parts of the ARC
conversion (such as removing retain and release calls) and helps you
to fix issues the migrator can’t handle automatically
Thanks.
The tool does not get rid of them for you, but simply adds retain/release code as need under the hood at the time of compile.
Those problems very well may go away when you get rid of old reference counting code.
EDIT: Further explanation:
In Xcode 4.2, in addition to syntax checking as you type, the new
Apple LLVM compiler makes it possible to offload the burden of manual
memory management to the compiler, introspecting your code to decide
when to release objects. Apple’s documentation describes ARC as
follows:
“Automatic Reference Counting (ARC) is a compiler-level feature that
simplifies the process of managing object lifetimes (memory
management) in Cocoa applications.”
In other words, ARC does not "strip" reference counting from your code, but rather does it on it's own under the hood. You no longer have to type release or retain or dealloc again. One thing the ARC needs to work is for it to do the reference counting entirely on it's own (with no user reference counting to "get in the way").
Took a long time to resolve, but both of these issues seemed to stem from some custom macros I was using. I had a macro for release-and-set-to-nil that I was using frequently, like this:
#define RELEASENIL(x) [(x) release]; \
(x) = nil;
I'm still not sure why, but for some reason, the ARC conversion tool didn't take this in stride, and choked on it, throwing the release warnings and the parse errors. (Some interaction with the preprocessor?) When I changed the macro to remove the release line, the conversion proceeded much more in line with my expectations.
And yes, it does of course remove the messages for you. (I'm answering my own question on the off chance that someone else ever has this issue.)

Resources