2

We are developing an app that we want to run on iOS 4.3 and above.

Our senior developer believes using ARC is a bad thing and causes crashes and problems in anything below iOS 5. Is this true? What problems could there be when using ARC on iOS 4.3?

I know you have to use unsafe_unretained instead of weak references. What issues could this cause?

Should we not use ARC at all if we are also developing for iOS 4.3 or is it possible to develop a solid app for both iOS 5 and above and iOS 4.3 using ARC?

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
user1038017
  • 61
  • 1
  • 6
  • 2
    Can't answer better than Rob. See the accepted answer in this thread:http://stackoverflow.com/questions/8760431/ios-to-arc-or-not-to-arc-pros-and-cons – Vin Jan 26 '12 at 15:23
  • 1
    user1038017, ARC improves the allocation pattern of most applications. It frequently reduces the "high water" mark of your memory allocations. This is very good on machines, such as the iPhone 3G, that are stuck at iOS v4.2.1. As `unsafe_unretained` has the exact same semantics as the `assign` allocation policy of a MRR app, you aren't changing anything that you already had to manage. ARC does not make your app unstable. The instability was always there. ARC does't particularly expose it. Andrew – adonoho Jan 27 '12 at 14:54

3 Answers3

6

There's no reason not to use ARC when deploying to 4.x. It's totally incorrect to say that ARC causes crashes and problems on anything below iOS 5. That totally missing the point and not understanding what ARC is probably.

ARC is a compile time "funkiness". That's what I like to call it anyway! It simply adds in the right number of retains and releases or autoreleases to make your objects stay around for as long as they should. I like to think of it as almost like turning objects into stack variables. So consider this code:

- (void)methodA {
    NSNumber *number = [[NSNumber alloc] initWithInt:5];
    [someObject doSomethingWithANumber:number];
}

ARC will add in a release of number when the number variable goes out of scope. In this case it goes out of scope when methodA returns. So consider this more elaborate bit of code:

- (void)methodB {
    NSNumber *number = [[NSNumber alloc] initWithInt:5];
    if (<some_expression>) {
        return;
    }
    [someObject doSomethingWithANumber:number];
}

In this case, without ARC we would have had to put in 2 [number release] calls. Once before the premature return and once at the end of the method. Obviously this is a contrived example by the way - it's just to show the idea. With ARC, we don't have to put in these 2 calls it does it for us. I think you can see the power of ARC here because in this scenario if your method got a bit bigger and more complex, you could very easily forget to release things before a premature return from a method.

Back to the point in hand about 4.x... You're right that you can't use weak references. This is because this is the only part of ARC that requires help from the runtime, and this isn't part of the runtime shipped with 4.x. The runtime will automatically nil out weak references when the object it's pointing to goes away. So if you have ObjectA having a weak reference to ObjectB (e.g. delegate pattern) then if ObjectB goes away because it's no longer in use, then ObjectA's reference will be nilled out. This only serves as a safety net in my opinion. You should be coding so that that scenario never occurs anyway. It's been the way ever since weak references came in and you just have to code in such a way as to not let it be an issue - something we've all been doing for many years already.

In my opinion, you should be using ARC. It will help you. You'll get much smaller code and more readable code because you don't have retains, releases and autoreleases all over you code. You'll get less crashes & leaks from incorrect memory management, something which we all have had problems with.

In short: USE ARC.

mattjgalloway
  • 34,792
  • 12
  • 100
  • 110
0

I strongly agree, they're identical to using assign in iOS4, however to suggest they are no more likely to cause crashes in this case is not thinking this through. Who writes code so it crashes? No-one. Do applications still crash despite this intention? Of course. Looming large across the spectrum of culprits is memory management and the raison d'être for ARC. Interestingly though the least caution iOS developers exercise is with assignment - and it's here the danger lies. How often have you seen code where delegates and datasources have not been zeroed in the dealloc? There's scarce hope the level of caution in dealing with these in ARC is going to increase as we delight at our cleaner code, nary a thought for the dangers of dangling pointers. This risk in iOS4 is not obvious and can be very difficult to trace.

ARC is the way forward however there are compelling reasons for those supporting applications in iOS4 to take a considered approach.

Joe
  • 1
-1

This is incorrect. In iOS4 the runtime will not automatically nil weak references, you can only use __unsafe_unretained (non-zeroing) rather than __weak (zeroing) which can lead to crashes. Some useful background reading here:

http://mikeash.com/pyblog/friday-qa-2010-07-16-zeroing-weak-references-in-objective-c.html

http://www.mikeash.com/pyblog/friday-qa-2011-09-30-automatic-reference-counting.html

Joe
  • 1
  • 1
    It can only lead to crashes if you code so that it might happen, though. We've all been coding this way for years. I don't see why people think that suddenly with ARC it means your apps *will* crash just because weak references are not automatically nilled. – mattjgalloway Jan 26 '12 at 16:30
  • Matt's right, unsafe_unretained objects are no more dangerous than the assigned pointers we've been using all along. It's just that the new weak references add a layer of safety that we hadn't had before. You're not open to any more crashes using unsafe_unretained variables than you had under manual memory management, so they should not be used as a reason to avoid ARC for 4.x deployment targets. – Brad Larson Jan 27 '12 at 22:33