January 24, 2012

Earlier this month I went down to Salt Lake City to do an on-site class for a company there. Rod Schmidt, the organizer of the SLC CocoaHeads chapter, was kind enough to delay their meeting by a week so I could join them.

One of the members, Patrick Cassell, runs an Apple news and commentary blog at iTechCrossroads. He did a brief interview, and posted it online.

I wasn’t quite expecting a verbatim interview, so like I guess like that’s how I actually speak and stuff. But there were some interesting questions.

April 19, 2011

This last weekend I taught an Objective-C and iOS bootcamp to a group of students and faculty at WVU down in Morgantown WV. They have a cool “AppLaunch” project going on, to inspire students to write real applications on iDevices and encourage an entrepreneurial spirit (sorry, link is broken now), and they invited me down to kick off the technical portion. Slides are available at my Free Talks for CocoaHeads page

A common question I got beforehand was “what’s the best way to get up to speed on this stuff?” That’s kind of like asking “what’s the best kind of pizza”. It all depends on where you’re coming from, where you want to go, and how fast.

If money is no object, take a Big Nerd Ranch class. In addition to teaching there, I have taken a number of Ranch classes from a bunch of different instructors, and they are all top-notch. The Ranch has a way of doing things that ends up with a really high quality product, enjoyable to both instructor and student. This will cost you a couple thousand dollars and take a week of your life, but you will be well on your way to iPhone programming studliness. Check out AnneKate Halsall’s Taming the Wild Dogcow tumblog for impressions and ah-has during the course of a class.

The next level down is books. I love books. I learned to program from books and magazines. Old folks may remember back in the day when computer magazines had pages of BASIC program listings. Keying those in and debugging the inevitable typos is how I learned to program. There are two books I really like for iOS programming: the Apress Beginning iPhone 6 Development: Exploring the iOS SDKby Dave Mark, Jack Nutting, Jeff LaMarche et.al.; and the Big Nerd Ranch iPhone Programming, the Big Nerd Ranch Guide by Aaron Hillegass and Joe Conway. I recommend people read both of them. If one book glosses over a topic the other covers in depth. Disclaimer: I’ve been the technical reviewer for the Apress Beginning iPhone books since the first edition.

What order to read them? If you’re strapped for time, read the Ranch one first. It’s short and to the point. Dedicate a weekend or a couple of evenings and type in everything. Then start working through the Apress book at your leisure.

If you’ve got more time, or you’re working over a longer period of time with other people, such as the Pittsburgh CocoaHeads Learn iPhone project, use the Apress book. It’s longer and wordier (764 vs 380 pages), but goes into topics in more detail. Some of the code is repetitious so you might not want to type in everything.

You’ll want some introductory books if you’ve never programmed before. The Aaron Hillegass Objective-C Programming: The Big Nerd Ranch Guide is very good. I’m partial to the Apress Learn C on the Mac by Dave Mark, followed by Learn Objective-C on the Mac the latter written by me and my hero Scott Knaster. This pair was designed to take you from “loops are cool!” up through Categories, Properties, and Predicates. If you already know C you can go straight into Learn Objective-C. If you already know how to program in something else and just want a quick brush-up on what’s peculiar to C, I’ve broken out the first two chapters of the first edition of Core Mac OS X Programming into a C Refresher. Learn Objective-C has an appendix on what weirdnesses to expect if you’re coming from other languages like VB or Java. I know I get frustrated when I have to wade through “loops are cool!” when picking up a new language, so it’s nice having different places you can catch the train.

Finally, take a look around your community. You may have an active CocoaHeads or an NSCoderNight chapter, or perhaps an iPhone programming MeetUp. If there’s not one now, start one! There’s nothing like having living breathing people to ask questions of, and to generally hang around with. You might discover one-off classes like what I did at WVU, or longer-term learning projects like what we’re doing at our local CocoaHeads.

March 31, 2011

A friend recently asked me about my opinions on the Time Capsule. I had the first generation device. It was OK, but slow, and eventually died the death of the power supply.

I have the latest gen now, 2TB, and love it. With 10.6 over a fast network, I don’t notice the hourly backups. One thing I did notice as time went on that the backups were getting kind of big. I want my individual machine backups to be under 1TB so I could archive them to some terrorbyte external drives I already have. I’d exceed that if I backed up too much junk too often.

My main goal for backups is to restore my $HOME data in the event of a machine failure. I don’t plan on restoring the OS or Applications from the backup. I’ll just use whatever OS is on the replacement machine or install my own, and I’ll install applications as I need them.

Backup Loupe is a great application for looking at your backups and seeing what’s being piggy. A file that’s only 50 megs is not a big deal, but it becomes a bigger deal if it gets touched regularly and gets backed up every hour. Using Backup Loupe, and general foresight, I have built this exclusion list over the last year or so. Unfortunately the list is not in any sane order. I’m not sure what order it’s listed, since it’s not chronological.

Some are pretty obvious:

~/.Trash – no need to backup trash.

/Library/Application Support, /Library/Caches and ~/Library/Caches, those will be re-created by applications. ~/Library/Application Support I do back up since it might have useful goodies. [edit: Mark Aufflick suggests preserving /Library/Application Support/Adobe. Personally I just use Lightroom and Photoshop CS5. Lightroom is pretty well behaved, and I’ll just reinstall Photoshop. But if you had the full Suite, that’d probably be a huge pain].

/Applications, I’ll just redownload and reinstall them.

/Users/bork is a test user I only use for development. No need to back that up.

The various parts peculiar to individual app or companies are there because they’re either big, can be regenerated, or an app touches a file often. Camino is one of them. I don’t use it very often, but every time I do I have to back up 50 megs. So its application support directory is on the chopping block. Similarly, Chrome gets updated every week, and is pretty big.

/Developer and /Xcode4 are there because I’d fill up the Time Capsule just from Xcode updates. I can always download the latest one if I’m setting up a new machine.

~/junk is a directory I use to throw junk into (hence the name). NoBackup is a similar directory at the top level. I have one in Movies too as a place to store one-off iMovie projects. Once I create the final movie the project can go bye-bye, and I usually don’t feel the need to back it up in the interim. I can get the original footage from the camera again. If it’s something larger or more important, I’ll leave it in ~/Movies, which does get backed up.

~/Downloads is another place for stuff I don’t want to delete right now, but won’t cry if it suddenly went away. If I want to keep it, I’ll put it somewhere that’s backed up.

Lightroom generates previews of photographs so that the UI is more responsive. Those can be regenerated later, so they don’t ned to be backed up.

All system files, including /Library/Printers,and /usr are things that would come with a fresh OS instal. Things in /usr/local I can re-install as needed. Same with /opt.

My music lives on another machine, so I don’t need to back up ~/Music

I check with Backup Loupe every now and then to make sure there’s not a new suprise that’s getting backed up.

Addendum: courtesy of brad@cynicalpeak, there’s other trash directories, /.Trashes, /Volumes/*/.Trashes if you have multiple disks. Also /var/folders is yet another cache location.

September 10, 2010

I’m curious about how static variables work. Presumably they aren’t stored in the stack, right? So how come you don’t have to store it as a pointer?

They’re just global variables, but with limited visibility. So their actual storage is off with all the other global variables, but nobody outside of that function can actually see it. like having a spy in their midst.

Where is that? I guess my confusion is that it seemed like the sort of thing you’d have to allocate memory for.

Have an illustration:

so the arrows show where stuff lives / ends up. arg and the local vars are on the stack.
The four bytes for the ‘blah‘ pointer is on the stack. The return from malloc is in the heap, and the static local is off hanging out with the globals.

I thought char * blah and static char blah were basically the same thing

char * blah has a short life span. Kind of like a firefly.

static char *blah has a long life span. Kind of like a roach that’ll never leave the kitchen. attacks with Raid™ notwithstanding.
Definitely a kill -9 situation then.

So with char * blah if you forget to free the memory before the function exits you can’t get to it again, right? Because the pointer to it is gone

if you do char *blah = malloc (23); and then exit the function before free() ing, then yes, it’s gone. It’s occupying space, but there’s no map to find it

July 22, 2010

I got a question a couple of weeks ago under the subject “Cross File Method Calling” from a friend who was struggling with Model/View/Controller. Like a lot of stuff, it’s easy to look at a concept like MVC, grasp the contents, and then have your brain go into vapor lock when faced with empty source files. This F# major scale only has six sharps in it. It looks pretty easy on paper. Then you try to play it on the bassoon. Oh my.

We had a nice chat that turned into more “how to reduce dependencies” rather than full-blown “here is MVC in all of its glory”. Specifics have been changed to protect the cool project he’s working on.

I have this: KitchenCombatViewController.m – I create 4 new UIViews: OvenView, FrigeView, PantryView, and BlenderView. These know how to draw themselves, I can layer them and hide/unhide them as needed. Works well.

Now in the touches routine in BlenderView, I want to call a method in another file, like setNeedsDisplay in PantryView. I can make an instance variable that points to it, but I don’t know how to initialize it to point to the PantryView.

Let’s take a step back. Here’s what I saw with the first sentence:

The next statement, having BlenderView talk to PantryView, would look like this

Which would work OK now. But as software evolves, you’ll find other places to do the same trick. “FrigeView will need to tell the OvenView this. And then the BlenderView will also need to tell the FrigeView that.” And before you know it, you’ve got a pretty complex web of interactions:

It might not happen immediately. It might not happen until the next version or two as you add features, but as you add more dependencies between objects, it becomes easier to add even more dependencies. Wonder what happens if you add another view into the mix later? You’ll probably end up with another N connections. And if you’re not careful with memory management, you’ll get retain cycles.

What you want to do is to reduce the number of individual points of contact between the moving pieces. The KitchenCombatViewController already knows about the four views. It creates, layers, shows and hides them after all. So it would be a good place for that logic:

Notice that the relationship between the controller and the views has become two-way. The views need to know about the controller so they can tell the controller “hey something Interesting happened to me. Other folks may or may not want to know about it”. But notice that there are much fewer direct interconnections between objects. If you need to have FrigeView’s touch handlers tweak the OvenView, it’s a line or two of code in the Combat controller rather than setting up a direct dependency relationship between the two.

Also, if you add a new view type, say a SinkView that needs to be updated as combat progresses, you don’t have to touch any of the other views. This last point is huge. You can extend the capabilities of your system without having to touch a lot of other places in the code. That’s fewer changes that could introduce bugs. Less chance of forgetting some detail, like “oh yeah, touches in the FrigeView really needs to tweak the SinkView too”.

That makes sense, but I’m not seeing how I do that “tell the combat controller” that something interesting happened?

If you want. When this method gets called, objects will already be a buffer (presumably on the caller’s stack) that will hold len pointers. You can fill this with your data structure’s contents to be iterated over. You can also return a pointer to your own storage via the state structure’s itemsPtr:

July 14, 2010

I occasionally get Questions From Friends over mail or AIM or IRC. Usually they’re simple things and quick to answer. I figured I’d put the answers here too in case anyone’s really bored on a rainy sunday afternoon.

besides autoreleasing the memory, what is the difference between the following two statements?

why would I ever NOT want to autorelease? Seems like the 2nd statement is easier

If you’re going to be immediately hanging on to it, the autorelease is wasted work,
or if you’re doing it inside of a tight loop – it’s better to get rid of it immediately rather than let a bunch of stuff accumulate in an autorelease pool. Of course, you can make and drain your own pool inside of your loop. Autorelease pools are pretty fast. But if you have a big spike of memory, say by accumulated autoreleased objects waiting for the grim reaper, that’ll push out things like mapped-in code segments, which may need to be brought back in later on. And on the phone, cycles count again, so it’s a hair more efficient to avoid autorelease. Just make sure you don’t accidentally forget to release it when you’re done.