Is ARC safe to use when deploying to iOS 4.x? - ios

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?

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.

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.

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

Related

Is it not possible to use "Analyze" with swift? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
Previously with objective-c code, I could "Analyze" - CMD + Shift + B and Xcode would warn me of all kinds of wrongdoings on my part.
It seems that with Swift, I can do no wrong! No warnings of any kind! But clearly there is a memory leak in my code.
Is there some setting I have to enable to get Swift to analyze my code properly? (I am aware I should use the profiler and test on an actual device, which I do, but I wonder why "Analyze" doesn't do anything.
Unfortunately no. Even many releases later, the latest version of XCode (6.4) still cannot do Swift analysis. The 'Analyze' option only works for the Objective C files in your project.
Let's hope the next version will have it, along with the refactoring capabilities which also are still limited to Objective C code.
To this moment (Xcode 8.3.x) Static Code analysis skips Swift code. Some Swift warnings cover some of the issues previously detected by the analyzer.
Also the upcoming Xcode 9 (presented in WWDC 2017) does not announce any change in this direction.
Many issues detected by the static Analyzer of Obj-C are for the most part prevented by the actual Swift language (e.g. unintended fall-through in switch statements). Other issues and scenarios formerly caught by the analyser, are now caught directly by the Swift compiler.
Many flows and scenarios leading to program crash - (e.g. accessing null pointers, leaving dangling pointers, or accessing released memory blocks) are hardly possible in Swift. Swift strong typing, heavy use of optionals, the requirement to completely cover protocols, and switch-case over enums, etc. remove another bunch of issues previously found by the analyzer.
A Swift static code analyzer will need to go to another level in analyzing program logic, which is much harder, and theoretically impossible to do completely.
So - although I'm quite thrilled to think of some future Xcode Analyzer, I wouldn't hold my breath waiting for it
Update:
As more and more people are down voting my post, just small update from my side. It seems that indeed apple just did allow for pressing option "Analyze" but in the background it does nothing (state for 2016.04.21, though I am not working on iOS for the moment and probably I don't have the latest version of Xcode).
below my original post:
Just for next readers of this article. At this moment Xcode 7 is already able to analyze also Swift projects. Refactoring is still not working though.
BR,
Darek

Swift UIKit Memory Management inefficiency

Note: I apologize if there are similar questions, but they are more specific like "UIMapView Kit Memory Leak issues", I am more concerned and really want to know in General Swift and ARC and the memory Management Issues with it.
I have done a couple of apps now in Xcode, however it was all done in Objective-C.
The memory management of UIKit objects(including UIViews and UIViewControllers) and any other object for that matter was easy to handle in Objective-C, and by easy I mean getting used to it after battling with it at some point in the Learning curve.
Now I am working with Swift trying to keep up with the "Cutting-Edge" technology. however I have noticed a slight issue with what I was able to pin down and control in Objective-C, Memory Management.
Swift comes in saying how easy is going to be for us to focus more on Code Development and not on memory management like its predecessor or soon-to-be predecessor.
However I have not yet found this benefit. I have been having a horrible time with memory management of my new app. Just creating a simple UIViewController with a few views can stack up memory that I don't longer need, few Mb's at a time.
keep in mind, I have been using deconstructor(Deinit in Swift), been assigning nil to values I no longer need to use, removing SubViews from Super Views manually thinking this was the problem, even using AutoReleasePool code segment.
autoreleasepool{
//Code looping through Swift Native Objects that potentially might lead to leaking
//But AutoReleasePool helps with this, supposedly.
}
Now the Question: Anyone here would know exactly what is the problem? Is it me doing something terrible with my code? or is there really a bug in Xcode and swift memory management? Have anyone else had this issue, have you solved it?
Here is a link explaining a bit this situation.
Problems of ARC in Swift?
ARC in Swift Apple Docs
Update:
You are right, I should post more about my situation: so here it goes.
I have memory starting at ~5mb as as soon as the app starts.
Once I start navigating around the app. I notice how memory starts to pile up little by little.
but the biggest spike of memory start to pile up when I use UIMapView of about 25+ Mbs.
when using just a regular UITableViewController it just piles up ~2mbs every time I push(to NavController) the same UITableViewController. When I tab that TableViewCell it opens another ViewController with a UIMapView, this is where the memory starts to pile up really good.
Rememeber I am just going back and forth navigating through the app. Just a total of 4 UIViewControllers including My Menu.
But here is the thing... All these memory SnapShots you see are after I stop navigating and go back to the main menu, the Root ViewController of my Navigation Controller.
Swift uses ARC in exactly the same way that ObjC does. If you're seeing a leak, you're probably creating a retain loop somewhere, and you would avoid those in almost exactly the same way as in ObjC (with the additional option of using unowned, but those are very similar to unsafe_unretained, so even that isn't a major change). If you're familiar with memory management in Cocoa, then you understand memory management in Swift. But we can't help based on the information you've given here (which mostly seems just commentary on Cocoa).
autoreleasepool{
//Code looping through Swift Native Objects that potentially might lead to leaking
//But AutoReleasePool helps with this, supposedly.
}
All that said, this comment hints at your mistake. The autorelease pool needs to go inside a loop where you are rapdly creating and destroying objects, not around it. Autoreleased objects are not released until the end of the pool block, or the end of the event loop. The latter is generally sufficient, but if you're generating and releasing lots of objects, then you sometimes have to drain the pool sooner. Autorelease pools are explained in the Advanced Memory Management Programming Guide. That said, they are not commonly needed for UIKit objects.
As a side note, the "Problems of ARC in Swift?" link you give seems to be unaware of the history of Garbage Collection in Cocoa. GC was tried by Apple on Mac and rejected by Cocoa devs. Apple deprecated GC and has subsequently removed it (I was at WWDC when they announced it was being deprecated; we applauded). It is even less applicable to iOS. An excellent discussion of this issue is in Why mobile web apps are slow. I'm not saying that GC is a bad thing. I'm saying that Apple is well aware of it, and actively chose not to incorporate it. They didn't just miss an opportunity.
EDIT: Your updated info looks like a pretty standard retain loop. I'd start with heap shot analysis to figure out what kinds of objects are involved. Make sure you're following the rules. And go from there, mostly with Instruments (especially the Allocations and Leaks instruments). One key is that view controllers should generally not retain other view controllers at all. They should talk to each other through the model. You must be careful using self in blocks. The normal rules. They're the same in ObjC and in Swift. But heap shot is definitely the place to start. Find out what is leaking; then figure out why.

Is Monocross ready for professional use on an iOS device?

When creating a simple app with Monocross (using MonoTouch) and compiling for an iOS device I get some bad warnings, like this:
Warning MT4112: The registrar found a generic type: MonoCross.Touch.MXTouchViewController`1. Registering generic types with ObjectiveC is not supported, and will lead to random behavior and/or crashes. (MT4112).
I've read all I can find about using MonoTouch with generics on an iOS device and it's mostly not supported. My app currently works on an actual device, but the warnings worries me.
I guess my question is, what is the state of Monocross when you get these warnings even with the simplest of apps? Is it still not ready for professional use or are the warnings not relevant for the way generics is used in Monocross?
I can also add the following from Xamarin.iOS docs:
"Xamarin.iOS does not currently support creating generic subclasses of the NSObject class"
Which is exactly what Monocross does, with for example the MXTouchTableViewController class.
There is some history to this: creating generic subclasses of NSObject has never been a supported scenario, but unfortunately MonoTouch never enforced, nor warned about this fact. So people of course ended up doing exactly this.
Then one day I had to track down something that looked like a true heisenbug, and it turned out (after many hours of frustrating debugging) to be because the project in question was using generic subclasses of NSObject. The exact details are not important, but that's when the warning was added to MonoTouch.
My point here is people have been using generic subclasses of NSObject for a long time, without running into any problems. If you test your app extensively (which you should do anyway), don't worry about this.
But if you do run into strange and inexplicable behavior, we'll most likely ask you to fix these warnings before looking into any claims that you've found a bug in MonoTouch.

iOS: Garbage collection

I know about iOS Automatic Reference Counting, which is compiler based feature. But, i have been going through many sites and confused with whether Garbage collection is also there or not on iOS program development? I know, ARC and GC is different each other. Some links says, GC is available for iOS and some links says GC is available only for Mac OS X development. But, i couldn't conclude saying whether the GC is there or not on iOS development? Please direct me the right path or link so that i can understand about it and try programming.
Thanks!
iOS has no method of Garbage Collection. Even so, Garbage Collection is entirely unnecessary (for all practical purposes) when ARC is used. ARC works its magic at compile time to do the reference counting for you thereby making it unnecessary (and actually non-allowed) to use any other sort of memory management.
Edit:
To clarify, OS X does currently support garbage collection, but it is deprecated (unbeknown to me until a few minutes ago) as of OS X Mountain Lion. iOS never has and never will support garbage collection. Any advantages of garbage collection are moot when compared to those of ARC, and Apple has made the move to (forcefully) nudge us in the right direction.
iOS does not have garbage collection

Does ARC manage memory for CGPDF types?

I'm working on a custom PDF library for iOS and noticed that there are explicit functions for retaining and releasing CGPDFDocumentRefs andPageRefs. Does ARC handle the retain/release of such opaque types?
No. ARC does not currently handle the memory management for anything except Obj-C objects (which CGPDF things aren't).
I had the same problem when I recently converted to ARC in PSPDFKit 1.8. After considering a lot of tricks, like bringing ARC to autorelease an item, or using associated values, I finally use a container class that manages the references on the CoreFoundation-Level.
It's tricky, as if you have a CGPDFPage and you release the CGPDFDocument, further calls to the CGPDFPage will crash, even if that one's retained. So be careful with the references.
Related, it's not a good idea to keep many CGPDFDocumentRefs open - they may need A LOT of memory, malloc's of 15MB are not unusual. So in my library I took great care that things get released fast when there's a memory warning.

Resources