Search
Rich's Mad Rants
Powered by Squarespace

Creating iOS 5 Apps Discussion > Use of static const vs. #define

Hi Rich, I've noticed that you use static const a lot. In other programming books and courses I've mostly seen #define used. Would you please explain why you opt for using static const instead? Why do we need to make these static?

For example, on page 150, instead of...

static const NSString *WeightHistoryChangedDefaultUnitsNotification = @"WeightHistory changed the default units";

...why not...

#define kKVOWeightChangeKey @"weightHistory"

Thanks!

December 23, 2011 | Unregistered CommenterScott

Typo in my example code in original post. It should be...

static NSString * const WeightHistoryChangedDefaultUnitsNotification = @"WeightHistory changed the default units";

I discovered this when, on page 155, I was getting a warning do to placement of the const keyword before NSString (making it a constant NSString, which it already is because it's immutable) vs. after NSString * (making it a constant pointer to and NSString that cannot be reassigned). Do I have that right?

Still, I would appreciate your explanation for my edification why we want to use static constant pointers here vs. just defining constants.

Thanks!

December 23, 2011 | Unregistered CommenterScott

It's mostly stylistic. I prefer to avoid using macros whenever possible, since macros are potentially unsafe.

Now, I assume that using static, properly declared constants will produce code that is easier for Xcode to understand--making things like compile-time type checking, code completion and static analysis work better--but I haven't actually tested that.

I also picked up this method of declaring NSStrings from Apple sample code. I don't know if it's their preferred approach, or if it's just something I stumbled upon--but I like it. Unfortunately, when it comes to objects it really only works for NSStrings. There are times when I'd like to create a static, const NSArray--but that doesn't seem to be possible.

December 23, 2011 | Unregistered CommenterRich

Cool, thanks for explaining. Following Apple's sample code seems like a sound approach. So, how are macros potentially unsafe? Also, in the case of your wanting to create a static const NSArray (but can't), what do you do instead? Thanks

(Btw, I get 4 notifications for every follow-up comment from your forum. I don't mind, just mentioning it fyi.)

December 23, 2011 | Unregistered CommenterScott

Well, #define is not part of the Objective-C program itself. Instead, it is handled by the preprocessor.

So,

#define VAL 5

Will literally go through your code and replace every instance of "VAL" with "5". It doesn't do any type checking. It doesn't respect scope.

Now, you're not likely to get into too much trouble with basic #define macros--but if you're creating function-like macros, you can easily create code with subtle bugs. Still, I had always been told to use const instead of #define wherever possible.

For something like NSArray, I usually create a private, read-only property, and then use dispatch_once to make sure the value is only calculated one time. It's a little more verbose, but (at least for now) it's my favorite technique:


NSArray* things(void) {

static NSArray* things;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{

things = [NSArray arrayWithObjects:@"Thing 1", @"Thing 2", nil];

});

return things;
}

December 23, 2011 | Registered CommenterRichard Warren

Thanks! I just happened to swing back by this thread looking for something I mentioned in my original post. Glad I did, because, even though I signed up for follow-up notifications, I didn't get one for your last response. I really appreciate your detailed explanation.

So, this is introducing some new programming styles/concepts. I've gone through a ton of books, videos, and courses on Obj-C and iOS and yet haven't seen these usage patterns until now. Based on the thoroughness, uniqueness, and consistency of adherence to best practices evident in your writing, though, I am confident in your suggestions and that this is more how things are really done when the rubber meets the road. I do not have a CS degree. Nor have I worked on a development team (other than my own). My programming knowledge has entirely come from commercial resources such as books, videos, and classroom courses. And I have observed many times in those offerings that important concepts either get glossed over or not covered at all (sometimes with a "beyond the scope" comment, or worse, times when it's not even mentioned what will not be mentioned). So when I see version control, unit testing, etc. covered in your book, I am hugely appreciative.

Can you suggest some additional resources to help me gain fundamental and practice knowledge of real-world programming styles such as you've adopted?

On a side note...

Fast forward a few years, and iTunes U will be an app-store-like environment where you can purchase courses that have prerequisites, etc. and result in legitimate accredited college degrees. Until then, coming into one's own as an iOS developer (or really, any environment) non-traditionally seems to be much more a journey through the wild wild west. Thanks for paving some roads to help make it a smoother ride. I am friends with Jonathan Lehr of About Objects. They offer exceptional classroom-based courses on C, Obj-C, and iOS. I know Jonathan is always looking for talented programmers who can teach and who are true to the fundamentals. If you're interested in that possible career path I would be glad to make an introduction.

December 24, 2011 | Unregistered CommenterScott

Scott, thanks for all the nice comments. I really wanted to include some topics that aren't often covered in computer programming books (like unit testing, source control, etc.). I mean, there are already a few great books on general iOS programming out there (Hillegass's is, without a doubt, my favorite). I didn't think we really needed another book that explained how to use scroll views. So, I wanted to go a bit deeper into some often ignored topics. I'm glad you like it.

On learning software engineering, depending on the school getting a CS degree might not help. I'm not going to say that CS degrees are unimportant--I learned a heck of a lot in mine, but then, I turned around and did actual research for several years after school--so that's different. Some of the best iOS programmers I know don't have a CS degree. So, not having a degree doesn't have to be a significant obstacle.

The best way to learn is to work on a project with a team. It's the old advice, if you want to get better, you always want to be the worst person in the band. You can learn a lot more from good team mates than you can from any book. If you can't work with a team, you can kind of simulate this by participating in online forums, and by downloading source code from good open source projects and looking through their code. Apple's developer forums are a great place to ask questions. I also often read through Stackoverflow. In fact, if you do a Google search for "#define vs const" you'll see a couple of threads on that topic.

Though, remember. A lot of this is just personal preference. Good software engineers often disagree on the best way to do things. I imagine some people may disagree with my NSArray approach. But it works well for my development style.

I feel like a lot of my opinions are things I've picked up here and there over the years. A lot of books hint at these topics, even if they don't describe them outright. There are some books that deal with them more directly. The "Pragmatic Programmer" book is very good. I know I've seen a number of similar books come out in recent years.

As far as teaching goes, I am actively organizing classes here in Houston. I do love to teach, so I'd be more than happy to talk with Jonathan. I won't be able to relocate (because of my wife's job), but that doesn't mean we can't do something together--even if it's only exchanging ideas.

I'm also really sorry about the notification problems. I'll try to contact you via email, and we can try to troubleshoot it offline. Though, that probably won't happen today or tomorrow due to Christmas stuff. Still, if you don't hear from me in a few days, feel free to nudge me.

December 24, 2011 | Unregistered CommenterRich

Just for completeness, I should point out that there's another approach to constant values, especially when they're used to configure the app. You can save the values in an external file that you then read and parse at runtime. Enterprise Java apps tend to do this using XML files. In Objective C we often use plists.

This has several advantages--all the configuration data is kept in one place, and you can change it without needing to recompile the app. Unfortunately, it also has some downsides. It can make the code harder to follow (especially if there are a number of different config files). Also, some people tend to take the is approach too far.

I've worked on projects where the content of each scene and even the transitions between scenes were defined in XML. The app itself was just a shell to parse the XML. This, in my opinion, is bad because the original engineer essentially created a custom programming language using XML. However, the syntax was incredibly hard to read. It was very immature and lacked a lot of features we ended up needing, and many of the tools we typically use to work with code simply didn't work with the XML. The end result was much harder to maintain.

For iOS, I tend to avoid configuration files.. After all, we have to recompile the project after making any changes anyway. And, the added computational effort needed to read and parse the files can cause performance problems. But some people swear by them.

December 24, 2011 | Registered CommenterRichard Warren

Oh, for learning software engineering techniques, I also recommend learning other programming languages--particularly languages that use radically different programming paradigms. Even if you never use the language for production code, it helps to broaden your sense of what programming can and should be. They also often describe why they take certain approaches. Even if you don't switch to the paradigm, you might be able to borrow a few ideas.

For example, I tend to use immutable objects a lot. That's something I picked up from studying functional programming (though Cocoa also has a lot of immutable classes).

Look at a functional programming language. Look at Ruby and how it handles metaprogramming. Look at Lisp (just to twist your brain). Look at the debates between static and dynamic languages, between strongly typed languages and other approaches (e.g. duck typing). Understanding the advantages and disadvantages of these different approaches will help you develop your own coding style.

December 24, 2011 | Registered CommenterRichard Warren

Great band analogy. Although I've been a drummer since I was 8, and I'm not sure if I've ever helped a bassist get better unless death stares for not keeping with a rhythm I'm laying down is considered professorial. I actually prefer books because I'm a fundamentalist and like to "know everything" about something before I do anything with that something. Idealism at its worst I guess. Books give a competent author the opportunity to lay things out in as much detail as necessary…better than videos or classroom instruction can facilitate. Problem is, many authors are lazy and skip going the extra mile. I appreciate that you didn't!

I've read a lot of books, watched a lot of videos, and attended a few classroom courses, too, on iOS and other programming languages. I've also studied Ruby/Ruby on Rails, PHP, MySQL, HTML/CSS/Javascript, and Python, and also built a few apps in PHP/MySQL. I agree with your advice about drawing on paradigms from other languages. Obj-C is the most universally pure OO language I've seen by far, though, so actually I think it's been my study of Obj-C that has benefitted my PHP development more than the other way around. Ruby on Rails was the first language I studied back in 2005. I attended Aaron Hillegas' Big Nerd Ranch Rails Bootcamp (he didn't teach the course though) pretty much right after reading Agile Web Development with Rails the first time. I was blown away by the unfamiliar design patterns and other aspects that were constantly referred to as common ground, and so shortly thereafter I picked up PHP, it being much more gentle with its permissive ability to dabble in OO but still do things procedurally, because that made more sense to a newcomer. I remember thinking back then that I must be stupid because I wasn't getting it. If it weren't for PHP, and in particular two authors (David Powell and Larry Ullman), I might've lost interest in programming altogether. Through their books, I discovered that I could get it if it was delivered by someone who knew what they were doing and also knew how to explain and teach what they were doing. It was a real eye-opener. I wonder though if I went back and checked out RoR again would I fall (back) in love with it as a web scripting language and want to rebuild all my PHP in RoR? I also detested the "complex" deployment (again, at the time, I was brand new to programming) and limited hosting availability back then for RoR. I know it's gotten much better.

I'm all for encapsulation and separation, but that XML proj you mentioned sounds painful. Give me convention over configuration any day! I have also steered clear of Java due to numerous horror stories about fragmentation in use, style, etc. from project to project. It amazes me that it has stayed #1 on the tiobe.com index, but I guess that's because of its enterprise audience. I definitely think times are changin' though, and iOS has not seen its greatest days yet.

Our 6-year old daughter just woke up. Time to go enjoy Christmas. Merry Christmas and happy holidays to you!

December 25, 2011 | Unregistered CommenterScott