PodSearch

Developing Perspective

#103: Coding Sins.

 

00:00:00 ◼   ► Hello, and welcome to Developing Perspective.

00:00:03 ◼   ► Developing Perspective is a podcast discussing news of note in iOS development, Apple, and

00:00:07 ◼   ► the like.

00:00:08 ◼   ► I'm your host, David Smith.

00:00:09 ◼   ► I'm an independent iOS and Mac developer based in Heron, Virginia.

00:00:12 ◼   ► This is show number 103.

00:00:15 ◼   ► Today is Tuesday, January 8th.

00:00:17 ◼   ► Developing Perspective is never longer than 15 minutes, so let's get started.

00:00:20 ◼   ► All right, so the topic I'm going to be talking about today, it relates to some, I guess you

00:00:24 ◼   ► could call it best practice, some lessons learned, some things like that.

00:00:28 ◼   ► And this is coming out of a great series of articles that I've linked in the show notes

00:00:32 ◼   ► that got started by a post by Ash Furrow talking about the seven deadly sins of a modern objective

00:00:38 ◼   ► sea.

00:00:39 ◼   ► And there was a great follow up to that written by Brett Simmons on Inessential talking about

00:00:45 ◼   ► some of those and adding into some of his own.

00:00:47 ◼   ► And there just are a lot of really good things to kind of talk about.

00:00:50 ◼   ► And this is, if you haven't already sort of caught on, this is going to be a fairly technical

00:00:54 ◼   ► This is a technical episode talking about fairly low level

00:00:57 ◼   ► things that an iOS developer or a Mac developer

00:01:01 ◼   ► would want to be aware of, would want to think about,

00:01:03 ◼   ► and would want to wrap their arms around.

00:01:07 ◼   ► This isn't one of my higher level, more hand-wavy ones.

00:01:10 ◼   ► So first I'm going to start off by talking about where it all

00:01:13 ◼   ► started, which is Ash Furrow's post,

00:01:15 ◼   ► The Seven Deadly Sins of the Modern Objective-C.

00:01:18 ◼   ► And the first one he talks about,

00:01:19 ◼   ► which I very much agree with, is it's

00:01:22 ◼   ► very dangerous to have one big nib file or zip file.

00:01:27 ◼   ► And really what you're trying to avoid there

00:01:29 ◼   ► is you're trying to avoid the situation where A, there's

00:01:33 ◼   ► the performance hit of having this massive view hierarchy all

00:01:37 ◼   ► put into a nib, because you have to load all of that dynamically

00:01:41 ◼   ► or at once when it loads.

00:01:43 ◼   ► And there's ways you can get around it in storyboarding.

00:01:46 ◼   ► But it's very dangerous to have too much of interface

00:01:49 ◼   ► in one nib file.

00:01:50 ◼   ► You can load multiple nibs.

00:01:52 ◼   ► And this is actually an example of something

00:01:53 ◼   ► that I do in Check the Weather, for example, where

00:01:57 ◼   ► the actual layout is all done with all

00:02:01 ◼   ► the different components or different nibs,

00:02:03 ◼   ► I guess is what I'm trying to get at.

00:02:05 ◼   ► The top, the left, right, and bottom

00:02:07 ◼   ► are all individual nibs, as well as the main dashboard,

00:02:10 ◼   ► if you're familiar with the app or if you can go look it up.

00:02:13 ◼   ► But they're all loaded independently,

00:02:15 ◼   ► rather than putting it into one big nib file

00:02:17 ◼   ► and then just moving views around.

00:02:18 ◼   ► And a lot of that is for the performance reason.

00:02:20 ◼   ► I don't load the side panels until the first time

00:02:22 ◼   ► the user wants to do it.

00:02:23 ◼   ► And it's something that I think in general

00:02:25 ◼   ► is something that you really want to make sure

00:02:28 ◼   ► that you avoid.

00:02:29 ◼   ► And it's good practice and good cleanliness

00:02:31 ◼   ► too to separate as much as you can things

00:02:34 ◼   ► into different concerns.

00:02:36 ◼   ► The next thing I want to talk about, which is his number two,

00:02:39 ◼   ► is not using dot syntax consistently.

00:02:42 ◼   ► A lot of people go back and forth about dot syntax

00:02:45 ◼   ► and whether it's the right thing to do.

00:02:47 ◼   ► Usually what it comes down to is where your background is.

00:02:51 ◼   ► If you're a long time Objective C programmer who

00:02:53 ◼   ► has been doing it since before the dot syntax was introduced,

00:02:56 ◼   ► you are probably anti it.

00:02:58 ◼   ► If you're coming from a language like Java, where it's

00:03:01 ◼   ► essentially that's the way that you would think about it,

00:03:04 ◼   ► you're probably more apt to use it.

00:03:05 ◼   ► Generally, I think the best thing he's saying here

00:03:07 ◼   ► is make sure you're using it consistently.

00:03:09 ◼   ► I think dot syntax works really well.

00:03:11 ◼   ► And the way I tend to use it is I

00:03:13 ◼   ► tend to use it pretty much exclusively for properties.

00:03:16 ◼   ► That's pretty much the only-- and essentially,

00:03:19 ◼   ► it's properties accessing internal IVRs.

00:03:21 ◼   ► I never use dot syntax when calling a method,

00:03:24 ◼   ► or even though you could.

00:03:25 ◼   ► I've seen an interesting thing recently.

00:03:27 ◼   ► Someone was talking about how they've

00:03:28 ◼   ► started using it for methods without side effects, which

00:03:33 ◼   ► I'm not so sure I'm convinced on either.

00:03:36 ◼   ► Because then you start getting into, well,

00:03:37 ◼   ► how do you define a side effect?

00:03:38 ◼   ► How do you know if it has a side effect?

00:03:40 ◼   ► An example of that would be calling, for example,

00:03:42 ◼   ► dot class on something.

00:03:44 ◼   ► So it sort of condenses it.

00:03:46 ◼   ► But any time you're using something, you have to make sure you use it consistently.

00:03:49 ◼   ► I think that's the more important thing.

00:03:53 ◼   ► The rest of his things, there's not a lot that I necessarily wanted to get into that

00:03:56 ◼   ► I didn't have as strong opinions about.

00:03:58 ◼   ► But I wanted to move over into Brett Simmons' response, which I think had a ton of really

00:04:03 ◼   ► good ones.

00:04:04 ◼   ► And his blog post is titled, "Coder's in the Hands of an Angry God," which is obviously

00:04:12 ◼   ► a follow-up to Seven Deadly Sins of the Modern Objective-C. And I think the thing that he

00:04:16 ◼   ► said that really caught my attention and something that I've been thinking about but never really

00:04:21 ◼   ► got into, one of the things Ash mentioned is that he says we don't do enough automated

00:04:25 ◼   ► testing. And I think that's maybe true. I come from a Rails background where that was

00:04:30 ◼   ► a much bigger thing. But in Objective-C, I've never found a really good way to do it. And

00:04:34 ◼   ► it's really hard and it's really annoying and there's not great tools for it. And a

00:04:37 ◼   ► lot of people say, "Well, you know, you just need to work on it." And that would encourage

00:04:41 ◼   ► tool makers, and so on.

00:04:43 ◼   ► But the reality is, automated testing doesn't necessarily,

00:04:47 ◼   ► it only pays off in very narrow areas in applications,

00:04:52 ◼   ► especially because a lot of it's UI based,

00:04:54 ◼   ► and all these types of problems that are tricky.

00:04:57 ◼   ► There's a lot of asynchronous code,

00:04:59 ◼   ► especially since GCD was introduced in iOS 4,

00:05:02 ◼   ► there's a lot of things that make it really tricky

00:05:05 ◼   ► to do good test coverage.

00:05:06 ◼   ► But I think Brett's response is, I think,

00:05:08 ◼   ► very, very reasonable, and something that I've been

00:05:11 ◼   ► I'm looking for-- and I think this is a great way--

00:05:14 ◼   ► is instead of that, to start introducing more NS asserts

00:05:18 ◼   ► into my code.

00:05:19 ◼   ► If you're not familiar with it, basically, NS assert

00:05:21 ◼   ► is you say NS assert, and then you pass in two parameters.

00:05:25 ◼   ► You pass in an expression who should

00:05:28 ◼   ► result to a Boolean and a description, basically.

00:05:32 ◼   ► And if that Boolean ever evaluates to false,

00:05:38 ◼   ► I think it is.

00:05:41 ◼   ► Yeah, I think it's false.

00:05:44 ◼   ► The assertion will blow up, and your app will stop.

00:05:48 ◼   ► And you'll be told, this assertion,

00:05:51 ◼   ► the thing that you said should always be true,

00:05:54 ◼   ► is in fact not.

00:05:55 ◼   ► And the reality of what that does

00:05:57 ◼   ► is it lets you put these checks into your code that'll catch

00:06:01 ◼   ► problems much more quickly.

00:06:03 ◼   ► And I think he has a great example.

00:06:06 ◼   ► NS assert not NS thread as main thread is what he's testing for.

00:06:11 ◼   ► And so it's a great way to put that into some code

00:06:13 ◼   ► that you know should only ever be called in the background.

00:06:16 ◼   ► And so if it is called on the main thread,

00:06:18 ◼   ► you want that app, you want it to be very aware.

00:06:24 ◼   ► So when you're testing, you're going to catch that.

00:06:26 ◼   ► Now, the other thing that's tricky with NS assert

00:06:29 ◼   ► is in theory, it should be fine to leave in there for production

00:06:33 ◼   ► once you've deployed it, but it always

00:06:34 ◼   ► makes me a little nervous when I'm putting in something

00:06:37 ◼   ► in my code that I know will crash rather than putting

00:06:40 ◼   ► the app into a funny state.

00:06:42 ◼   ► That's always a kind of tricky thing.

00:06:43 ◼   ► In theory, if you're writing good assertions,

00:06:44 ◼   ► it shouldn't matter.

00:06:45 ◼   ► But that's the only part that I'm always a little uneasy about.

00:06:48 ◼   ► But generally speaking, that just

00:06:49 ◼   ► means you have to be very careful and thoughtful about how

00:06:52 ◼   ► you use them rather than going-- sort of just putting them

00:06:54 ◼   ► in willy-nilly.

00:06:56 ◼   ► The next areas that I wanted to talk about

00:06:58 ◼   ► is something that he actually has-- Brent actually

00:07:00 ◼   ► had a whole blog post about, which

00:07:02 ◼   ► is talking about the UITableViewCell is not a controller.

00:07:05 ◼   ► There's been a whole series of things

00:07:07 ◼   ► that he talked about this.

00:07:08 ◼   ► But the big thing that I think he mentioned here

00:07:11 ◼   ► that I thought was really clever or is important

00:07:14 ◼   ► is that to try as much as we can to make sure

00:07:17 ◼   ► that our UITableViewCells don't know very much about the model

00:07:22 ◼   ► they're displaying.

00:07:23 ◼   ► For them not to turn into the controller,

00:07:25 ◼   ► for them to not be doing a lot of the stuff that

00:07:28 ◼   ► should really be outside of them.

00:07:30 ◼   ► A UITableViewCell should really just be a display.

00:07:33 ◼   ► It shouldn't really care too much about what it's displaying.

00:07:37 ◼   ► This is something I know I've run into myself, where

00:07:39 ◼   ► it's often easy to think, well, I'll just do a custom TableView

00:07:42 ◼   ► Cell.

00:07:42 ◼   ► I'll pass in my model object.

00:07:43 ◼   ► And then the cell will take care of displaying that.

00:07:47 ◼   ► And then I've gotten bitten by that.

00:07:49 ◼   ► An example of that is where in my audiobooks app,

00:07:53 ◼   ► I display a lot of books.

00:07:54 ◼   ► So I have a custom TableViewCell for displaying a book,

00:07:56 ◼   ► a title, an author, a type, those types of things.

00:07:59 ◼   ► And most of the time, it's all coming out of my core data

00:08:02 ◼   ► object is what I'm displaying.

00:08:04 ◼   ► It's my book object.

00:08:06 ◼   ► But there's an area where I display popular books.

00:08:08 ◼   ► And those are actually coming out of a JSON blob,

00:08:10 ◼   ► and so they're actually a dictionary.

00:08:12 ◼   ► And so it's kind of awkward where I was originally

00:08:16 ◼   ► doing some hard coding to be pulling directly

00:08:18 ◼   ► from a book, NS managed object.

00:08:21 ◼   ► And suddenly, it's like, that doesn't really work.

00:08:23 ◼   ► And I have to re-architect and change it.

00:08:25 ◼   ► And I think what he's saying here

00:08:26 ◼   ► is very true where you just want to make sure

00:08:29 ◼   ► that your UITableView cells are as sort of dumb as to what

00:08:33 ◼   ► they're displaying as possible.

00:08:35 ◼   ► And you can do that in a couple of different ways,

00:08:37 ◼   ► but what you never want to do is really

00:08:39 ◼   ► create a tight coupling between your model and a UITableView

00:08:42 ◼   ► cell.

00:08:43 ◼   ► You want to put something in between there

00:08:44 ◼   ► that gives you much more flexibility down the road.

00:08:48 ◼   ► Other things he talks about that I think are really good--

00:08:50 ◼   ► not turning on hosy level warnings

00:08:53 ◼   ► or not treating warnings as errors.

00:08:55 ◼   ► These are just kind of obvious things

00:08:57 ◼   ► where the LLVM especially is an amazing compiler.

00:09:01 ◼   ► And if you're doing things that-- LLVM can tell you

00:09:05 ◼   ► tons of problems with your code well before you actually

00:09:08 ◼   ► would need to, or far earlier than you'd notice them.

00:09:12 ◼   ► And so anything that it tells you is probably--

00:09:15 ◼   ► it's like, this is a warning.

00:09:17 ◼   ► This is something you may or may not want to do.

00:09:19 ◼   ► It's probably something you don't want to do.

00:09:21 ◼   ► It's just in general-- and I would say--

00:09:23 ◼   ► I've been doing this for a long time,

00:09:24 ◼   ► but the compiler is still 10 times smarter than I am.

00:09:27 ◼   ► So be careful about that.

00:09:28 ◼   ► And same thing with static analyzer.

00:09:29 ◼   ► Make sure every static analyzer issue you address.

00:09:32 ◼   ► The static analyzer is very smart.

00:09:34 ◼   ► It's catching really low-level problems

00:09:37 ◼   ► that you'd almost certainly not be able to, at least not

00:09:40 ◼   ► right away.

00:09:41 ◼   ► He talks about making sure you're looking at the crash

00:09:43 ◼   ► logs in iTunes Connect.

00:09:45 ◼   ► I recently found this to be really helpful.

00:09:47 ◼   ► I think since IOS 5, when iCloud was introduced,

00:09:50 ◼   ► and I believe crash reports are now sent automatically,

00:09:53 ◼   ► rather than having to be done via iTunes Sync.

00:09:55 ◼   ► There's tons of them usually.

00:09:57 ◼   ► They're really helpful.

00:09:58 ◼   ► I've been able to track down lots of little problems with that.

00:10:01 ◼   ► And any time I do an update, the first thing I do--

00:10:05 ◼   ► or the last thing I do, the first thing

00:10:07 ◼   ► of the actual submission process is I go in and make sure

00:10:09 ◼   ► that I've addressed all of those.

00:10:11 ◼   ► I pull up Refresh the Report List in iTunes Connect.

00:10:13 ◼   ► It's really helpful.

00:10:14 ◼   ► You don't have to do your own crash reporting or any kind

00:10:16 ◼   ► of mechanism like that.

00:10:17 ◼   ► It's just all baked into iTunes Connect and very helpful.

00:10:21 ◼   ► Another thing is putting things in .h files that

00:10:24 ◼   ► shouldn't be public.

00:10:25 ◼   ► And this is something that I used to do a lot

00:10:27 ◼   ► and have recently been trying really hard to fight against.

00:10:29 ◼   ► And I think it's really helped to really clean up my code.

00:10:32 ◼   ► It is basically-- it's a little tricky in the way

00:10:35 ◼   ► that Objective-C does structures things,

00:10:38 ◼   ► because you don't have the same level of-- if you're coming

00:10:41 ◼   ► from a Java background where you had the four levels of publicity,

00:10:45 ◼   ► basically, was it public, protected, private, and class,

00:10:50 ◼   ► something like that.

00:10:51 ◼   ► It's been a long time since I did good Java.

00:10:53 ◼   ► So, but anyway, what you really want to do is,

00:10:55 ◼   ► especially if you're going to be putting properties

00:10:57 ◼   ► or things for a class that no one else should be aware of,

00:11:00 ◼   ► put them as a class extension in the .m file.

00:11:02 ◼   ► Don't put them in the .h file.

00:11:04 ◼   ► The .h file should be as simple and straightforward

00:11:05 ◼   ► as possible, because you have to remember,

00:11:07 ◼   ► the person who's going to be having to work out

00:11:09 ◼   ► how this class works is probably going to be you.

00:11:11 ◼   ► And as smart as you think you are,

00:11:13 ◼   ► your future self is likely not as smart as you.

00:11:16 ◼   ► So be careful about that.

00:11:18 ◼   ► Other things that he says that I think are really good

00:11:20 ◼   ► is making sure you use pragma mark, which

00:11:22 ◼   ► is just a great way to structure and organize your code.

00:11:25 ◼   ► And the last one I want to talk about

00:11:26 ◼   ► is using instruments for performance testing and memory

00:11:29 ◼   ► analysis.

00:11:30 ◼   ► And I think this has become especially helpful and important

00:11:33 ◼   ► as the platform has improved and developed over time.

00:11:40 ◼   ► There's a lot of these things where

00:11:42 ◼   ► the things that are going to be able to differentiate

00:11:44 ◼   ► your application is going to be speed and performance

00:11:47 ◼   ► and reliability in a way that-- even

00:11:50 ◼   ► it's like a weather app, right?

00:11:52 ◼   ► I was building an app that was competing in a space that

00:11:54 ◼   ► was incredibly competitive.

00:11:56 ◼   ► I mean, there is a whole category with thousands

00:11:58 ◼   ► of apps that do this.

00:11:59 ◼   ► How do you differentiate yourself?

00:12:00 ◼   ► And one of the things you have to do

00:12:02 ◼   ► there is to work hard on performance

00:12:04 ◼   ► and those types of things.

00:12:05 ◼   ► I spent huge amounts of time in instruments

00:12:07 ◼   ► doing-- looking at where are the slow parts of my app?

00:12:10 ◼   ► How can I improve that?

00:12:12 ◼   ► Looking for hiccups and bugs, looking for memory load

00:12:14 ◼   ► over time.

00:12:15 ◼   ► All these kinds of problems that you

00:12:17 ◼   ► can improve your application in a way

00:12:20 ◼   ► that the user may not necessarily

00:12:21 ◼   ► notice in a way that is tangible.

00:12:23 ◼   ► It's not like having an impressive graphic design

00:12:26 ◼   ► or something where people are going to see it directly.

00:12:29 ◼   ► But I think people will notice, and it's kind of that latent,

00:12:31 ◼   ► this is a good app.

00:12:32 ◼   ► It's fast.

00:12:33 ◼   ► It's performant.

00:12:34 ◼   ► And you, of course, want to also be doing your performance

00:12:36 ◼   ► testing on slow devices.

00:12:38 ◼   ► I think right now, my typical baseline

00:12:40 ◼   ► is the iPhone 4, which I think gives me

00:12:43 ◼   ► a pretty good coverage.

00:12:45 ◼   ► It's not-- the 3GS I'll sometimes use,

00:12:48 ◼   ► But it's not as much of something that I use these days, just mostly because it's a relatively

00:12:55 ◼   ► small percentage of users, in my case, that use that.

00:12:59 ◼   ► I'm bringing up the stats.

00:13:01 ◼   ► It's about 6% of my users are using 3GSs, which is a pretty low number.

00:13:07 ◼   ► Whereas compared to the iPhone 4, it's about 35%.

00:13:11 ◼   ► And if you go iPhone 4 and up, it's 94%.

00:13:16 ◼   ► So if I can use the iPhone 4 as a basis,

00:13:18 ◼   ► I think it gets pretty good coverage,

00:13:19 ◼   ► even though the 3GS technically supports iOS 6

00:13:22 ◼   ► and all those kinds of things.

00:13:23 ◼   ► But that's typically what I've been

00:13:24 ◼   ► doing as a performance base.

00:13:25 ◼   ► And it seems to work pretty well,

00:13:27 ◼   ► especially because the 4 was the first of the A processors.

00:13:30 ◼   ► I think it was the A4 inside of it,

00:13:32 ◼   ► which gives you a really strong baseline to be working from.

00:13:36 ◼   ► You can do a lot.

00:13:38 ◼   ► If you're trying to get 60 frames a second animations

00:13:40 ◼   ► and things, that's something that is usually

00:13:43 ◼   ► possible on an iPhone 4 in some places on the 3GS.

00:13:45 ◼   ► You just can't do it.

00:13:46 ◼   ► Um, so anyway, those are just some of these thoughts.

00:13:49 ◼   ► I said, these are great links in the show notes for you to go through and just read

00:13:52 ◼   ► through and think about the reason I'm doing it now is again, it's just kind of

00:13:56 ◼   ► this, as we're, you're starting into the new year and you're starting to think

00:13:59 ◼   ► about new projects, new ways to do things.

00:14:01 ◼   ► These are just some things to be thinking about and to kind of make sure that

00:14:04 ◼   ► you're evaluating yourself of, you know, am I making writing as quality coded?

00:14:09 ◼   ► I could be, are there things I could be doing that are better and things that I

00:14:11 ◼   ► could be doing that are more useful to my future self?

00:14:15 ◼   ► So, anyway, that's it for today's show.

00:14:18 ◼   ► As always, if you have questions, comments, concerns, or complaints, I'm on Twitter @_DavidSmith,

00:14:22 ◼   ► I'm on AppNet @DavidSmith.

00:14:25 ◼   ► You can email me, david@david-smith.org, if you have questions about the show.

00:14:29 ◼   ► Otherwise, I hope you have a good week, happy coding, and I'll talk to you on Thursday.

00:14:32 ◼   ► Bye.