I didn’t see any way to comment on Mr. Hall’s site, so I have to write here. I won’t repeat what Mr. Hall said, just comment. But I do need to borrow his list since that’s what I commenting on!
I will agree. Automatic Reference Counting (ARC) is a huge win. While memory management in Cocoa development was never difficult, so long as you knew and followed the rules, it still tripped a lot of people up and yes, you had to know and follow the rules. ARC doesn’t eliminate the rules, just hides them. Code is simpler, more straightforward. And with runtime-support for things like zeroing-weak-references, life is pretty good. You cannot fully escape needing to know the rules, but ARC does make life so much better. There’s no reason not to use it.
Prefer Blocks Where Possible
I do love blocks. It takes a little bit to wrap your head around the concept, but blocks should not be avoided. First, the OS API’s are evolving to standardize upon blocks for a great many things, so in many respects Apple is forcing you to adopt blocks. You will be assimilated!
Second, blocks do provide a lot of simplicity of code because the logic is “right there”. Plus since you can reference data outside the scope, it can alleviate a lot of the infrastructure and overhead you’d have to create merely to pass data around. It’s pretty nice.
That said, it’s not all rosy. Blocks can complicate memory management (see blow). As well, the nesting of blocks can make your code rather unreadable. Plus it’s very easy to miss that you’re using a block since what denotes it is merely a caret ^. I’m still playing around with code formatting to manage this better. But the trade-off is with the block “right there” the code and logic gets centralized, without some need to go hunting around source files to find the other methods to make the logic go. So, there’s trade-off.
Beware of Retain Cycles With Blocks
Indeed. Memory management changes with blocks. What’s more confusing is that ARC changes some of the rules, like that __block retains under ARC, so you may need to use __weak, or even sometimes __unsafe_unretained. And sometimes, retaining “self” isn’t a big deal depending how the block is being used and the flow of code. But no matter what you must specifically do, you just have to get used to all of this. New features like ARC and blocks are great, but come with their own perils.
Forget Threads, Use GCD
On the whole I love me some Grand Central Dispatch. I use it extensively, and there’s so much more to it than just dispatch_async(). Lots of great stuff and GCD really does simplify programming. I mean, it uses blocks, so it gains a lot of those advantages (and disadvantages). And writing threaded programming hasn’t been easier.
But that said, threads are still appropriate. First, you might actually find that using NSOperation and NSOperationQueue’s may be more suitable. But that doesn’t mean NSThread and things like NSLock and NSConditionLock should be forgotten. On a project I’m presently working on, the best solution of all the “concurrency” technologies was to use an NSThread — it just make more logical sense in terms of code structure.
So, embrace GCD, just don’t forget the other options.
Singletons / Shared Objects
Yes, the new dispatch_once() pattern for Singletons is useful, but you should understand the old pattern — which is perhaps less relevant with ARC as well. And note of course all the debate behind why Singletons are good and bad, useful and not useful, appropriate and sometimes not.
Mr. Hall alludes to how costly it can be to create an NSDateFormatter many times. I’m curious what his use case was. Sure, if you have a piece of code that is invoked a lot and you always create and destroy an NSDateFormatter in there, that will be expensive. But is a Singleton the right solution? That too may be overkill, when merely allocating the NSDateFormatter once as a class data member may be sufficient. All depends upon your needs.
Storyboard is Just for Rapid Prototypes
I have to disagree here.
I do think it makes for a great prototyping solution, and I do think it isn’t quite conducive to all sorts of applications. But like all tools, you have to know it, understand it, and then you can determine when it’s the right tool for the job. You can do some legit work in it. kwikkEmail was written with Storyboard, and a current more complex project is using it as well. No, it’s not all roses, but it does provide a lot of useful capability.
Only Use XIBs for Very Basic Layouts
This I strongly disagree with. I can only assume, based upon his comments, that Mr. Hall must construct all of his GUI’s by hand in code. I cannot see how that’s superior, but then maybe that best fits his particular needs of his particular app requirements.
I’ve been writing Mac software for about 20 years, and was one of the first people outside of Apple to work with Rhapsody (joys of working at Metrowerks during that time period). I’ve been using nibs and xibs and now storyboard for some time. Maybe that’s my bias? Or if Mr. Hall comes from a Ruby on Rails world and is more used to making his GUI with .erb’s, then perhaps that’s why he has his preference.
Or maybe he just needs to elaborate more upon his stance.
In the end, there’s no one dogmatic way to proceed. Even in my use of Storyboards, sometimes I have to do things like dynamically create my UITableViewCell’s or load them from a xib. There are many techniques, and it’s worthwhile to know as many techniques as possible so you can pick the best solution.
Keep Your Project Organized
Amen to that.
Embrace Open Source
Very much so. The new breed of iOS developers are writing and using open source like crazy. Github is your friend.
I haven’t looked much into CocoaPods, because last time I checked it was just starting out and didn’t have enough traction. I might want to look at it again.
Meantime tho, Github, submodules, etc. works quite well.
Learn to Love Stack Overflow
Indeed. That and just Google searching. Developers today love to share what they’ve learned (I’ve done the same on this and other blogs), especially if it can help other people and save them the same pain we just went through. It’s wonderful to see and participate in such a vibrant community. Be a part of it.
Code should strive to be graceful, regardless.
It is good to move forward and adopt new things, while not totally shunning the old. But in the end, you have to look at what features matter towards the proper development of your product AND what your users/customers need.
A colleague of mine still struggles to support ancient Macs, because he works primarily in the education market and many schools still have really old Macs. If he suddenly said he was only going to support Mac OS X 10.8 (Mountain Lion) running on MacBook Pro Retina’s, he’d be screwing himself out of almost his entire customer base.
For most iOS development work, supporting iOS 5 as a minimum is reasonable because it’s how the hardware is progressing, how Apple works to manage updates to both hardware and software, and there are so few people still using pre-iOS5 OS’s and devices AND that are purchasing software. If you can determine your target market is still in that minority space, then of course be sure to serve them. But for most iOS devs, we can move on.
Just don’t forget to test. If you say you support iOS 5, you need to test on it and support it. And no, the simulator isn’t always the best way to test it. Sure, it’s a good start, but I’ve found differences between how the device works vs. the simulator (confirmed Apple bugs in this regard)… and let’s of course ignore the limitations of the simulator. Yes it’s hard to maintain the hardware, but welcome to being a developer.
Not much to comment on here.
Localize From the Start
I agree with this. You may not see the benefits of localization now, but someday you may see that’s a market to chase.
I sometimes wish Apple had a better way of getting crash logs to us.
While the App Store concept is great, putting an impenetrable barrier between users and the developer hurts sometimes, be it getting crash logs or just interacting with the user — they’d rather bad-mouth the app in the App Store or post a poor rating there, instead of telling the developer, who then has no real recourse for responding to those comments.
Use this always. Don’t make it a special build thing to do, because you’ll forget to. Just do it always, as a part of every build. Sure it takes a little time, but you can be sure the code you just wrote isn’t a problem.
Red herrings? I’ve had a few, but it’s not a big deal. It may be that the code looks suspect but if then you know it’s not, you can suppress the analysis around that chunk of code. I’ve been far more thankful than not for code analysis.
Yes. Run this. Use this app. There are LOTS of tools you can use to analyze your app, and you should get familiar with all of them. They will make for a better product.
I like to run it after any major portion of the app gets changed. So I just finished up a new feature? Hammer on it with Instruments to ensure things are solid. Getting ready for a release? Run the whole app through to see how things are performing and if some interaction effect came about because of things changed.
I’ll also add to look at the various Debug options in the Xcode “scheme” you’re using. Simple things like turning on Zombie tracking can be useful at times. Just another tool, be aware of when to use it.
Would I Add Anything?
Mr. Hall’s list is a good one. What would I add to it?
Use Version Control – I don’t care if you use svn, git, mercurial, whatever. Use something. Even if it’s just you working alone. There will come a time when you wish you could undo what you just did, and version control will enable that. My preference these days is git, and I think that’s a good place to start if you haven’t used version control before.
Use the version control you chose – Don’t just make the initial repo and commit here and there. Really use the thing. If you are going off to work on a new feature, make a branch and work in it. Commit early, commit often. Commit your changes in small chunks. It may seem silly, especially if you work alone, especially if you have never used version control before… but it’s like making a backup, that you just won’t fully appreciate it until you need it.
Grow – always seek to grow. Read all you can. Watch what other developers do, other apps that come out, to see the direction things are moving in. Understand what they are doing, what problems they are trying to overcome, what they are trying to do better…then try to do better than they did. You have to understand what’s going on around you, but then you want to try to lead and not follow. And program… a lot. Don’t be afraid to experiment and throw things out. Dabble with some new OS technology, just because you can, or it’s interesting.
Seek input from others – you don’t know it all, and you don’t always know what’s best. If you have customers listen to them. You don’t have to do precisely what they say, but delve below what they are saying to why they are saying it. You are trying to empower them, to make their lives better, and often they don’t know best what they want or how to articulate that to you. It’s tough to figure that out, but that’s what we have to do. And often, collaborating with others will help you better get there, will help you have better designs.
Core Data is awesome – Core Data is great, but it’s not everything. It’s not a database, it’s object graph management. If you need a database, use SQLite. Use it as appropriate.
Prototyping – Storyboard can be useful for prototyping, but I’ve found better tools. For example, Balsamiq is really cool for GUI mockups. I like using the Core Data modeler to design and visualize object models, even if I’m not going to use Core Data in the end. I’m still wishing for a good UML tool on Mac OS X… maybe I should look again, maybe the landscape has changed.
Just have fun. 🙂