Borkware Miniblog

April 13, 2012

Stuff Going On At The Ranch

Filed under: Big Nerd Ranch, meta, programming, Visix, work, writing — Mark Dalrymple @ 8:48 pm

In case folks are dying to read more of my technical writing, I’ve been writing a lot of material over at the Big Nerd Ranch Weblog, including some gems like:

Well, OK, that’s everything, even the not-so-gemmy. For the forseeable future my geek writing will be over there, and I’ll reserve this weblog for cute Vikki pictures:

IMG 0005 IMG 0057 IMG 0090 IMG 0175 IMG 0191 IMG 0219 IMG 0427 Leave a Comment

November 3, 2011

Outlet Collections

Filed under: Cycling Fusion, iPhone, programming, work — Mark Dalrymple @ 12:29 pm

A quick post to explain my tweet.

Screen shot 2011 11 03 at 11 41 55 AM

TL;DR: I can batch show and hide UIViews really easily now. Easier than setting up a bunch of outlets, fiddling with tags, making dummy views, or groveling through the view hierarchy.

I bet it’s Cocoa 101 nowadays, but they were new to me, pretty much seeing the reference when dragging a connection to header files (which I never do) and promptly forgetting about them. I might have seen reference to them in a WWDC sessions or something. But finally now I had a real use. Yay! For a lot of this stuff I need to actually use it for Something Real before it sticks in my brain. I can learn stuff by doing, but I’m lousy at memorization. Just look at my history grades during high school. On second thought, please don’t.

RideBuddy™ is one of the new apps coming from Cycling Fusion. Amongst a ton of other stuff, RideBuddy lets you track workout time in various heart zones – ranges of heart rates that have different benefits and consequences to the body. We like the Sally Edwards Heart Zones® system, which is a five-zone system based on certain physiological markers. I won’t get into specifics here, you can join the Cycling Fusion Winter Training in January and get the full details.

Five zones are kind of a lot for a beginner or just a casual rider to wrap their mind around, so Sally created Zoning™, a friendlier three-zone system and a color-coded heart rate monitor. It’s only three zones, but it’s based on the same physiological markers as the five-zone system. You can get a lot of health and training benefit by using the three zone system, and can graduate to the five-zone system when you feel up to it.

My stuff needs to support both. So, I have a number of screens like this one:

Two zone models

Something that’ll support three zones or five zones. Internally I can support from one to five zones. The code that adjusts the layouts based on the zone system in-use hides everything zone-related, then populates and enables stuff zone-by-zone until it runs out of zones. In the above screenie I have four objects per zone: two static labels and two text fields. zone zone zone.

To simplify that work, I have five IBOutletCollection(UIView)s — one for each zone. I walk through all of them to Hide All The Things, then walk the zones enabling a particular collection and populating items until I run out of zones. If I don’t hit a collection, it stays hidden.

Understandably, this is so much nicer than setting up an IBOutlet for each label and text field and making the connections. Or setting a tag on the items. Or groveling through the view hierarchy showing and hiding things. Or having a dummy UIView just to be a container. Just add the outlet collection and make connections in IB.

Markus Möller on Twitter “uses them for animating / moving groups of views. Better than putting them all in a container view. Less hierarchy.” which is another excellent use.

 

August 16, 2011

My First App: Class Builder

Filed under: cycling, iPhone, programming, work — Mark Dalrymple @ 2:02 pm

Class builder beauty

My first App got accepted into the AppStore yesterday – Cycling Fusion’s Class Builder™. Woot! Amazingly enough, it went through the approval process without a peep. There’s screen shots and tutorial videos (some still in the making – didn’t expect AppStore approval so quickly) at the link. And it’s at the AppStore.

Class Builder is a tool for Indoor Cycling (a.k.a. “Spinning®”) instructors to lead better classes. Rather than juggling an ipod, sheets of paper or 3×5 cards, and a stopwatch; instructors can plug their Device into the club sound system, run the class, and have cues pop up at the proper time during the class. They can also configure pre-class and post-class music for ambience before and afterwards. If the club has a projector, the instructor can plug their Device into the projector and show everyone the ride profile, along with additional information like current cadence / power / HeartZone®. A slideshow of photos can be shown during the pre-class time to help set the mood.

Despite “Class” in the name, this has nothing to do with programming.

Folks have asked me what I’ve been up to in the year-and-change since I left Google to work with Cycling Fusion. This is it, and the usual billion other things that go on when you work at a startup (along with the major update to AMOSXP)

The code is pretty much all mine, end-to-end. 13,000 non-comment / non-whitespace / non-brace LoC, 84 classes, 32 html files, and 677 .pngs. Not huge, but respectable. It was my first time really to work on something small enough that could be coded by a single programmer – usually I work on behind-the-scenes stuff that nobody else wants to touch. App design was by me and Gene Nacey, the fearless leader of Cycling Fusion. Graphic design by Emanuel Rufino and me. Luckily I now have the Photoshop skills to convert between an inspired artist and the user interface, to tone things down or amp them up as needed to fit the demands of the UI.

Class Builder is a part of the overall Cycling Fusion strategy for bringing the worlds of Indoor and Outdoor cycling together. We’re revolutionizing Indoor Cycling as we now know it through curriculum and certification, targeted training programs, web-based tools, mobile device apps, licensable music and an online video training library. Our big coming-out party is in the fall. If you’re into that kind of stuff, come on down to the ICI Pro Conference in October and check us out.

May 6, 2011

Blast from the past: gprof

Filed under: history, programming, Random, Visix — Mark Dalrymple @ 1:56 pm

Dino rific

I stumbled across this little tutorial I wrote back in the mists of time, probably around 1996 or 1997.  And it was based on a tutorial I wrote at Visix, probably in 1993 during one of our Optimization Parties.  It describes how to read the output of gprof, a profiling tool available on most unix systems.  It’s even still there on Mac OS X.  So you kids with your fancy Shark and Instruments, here’s what some of your elders used.

gprof is not a GNU tool, even though it has the leading “g”.  That “g” probably stands for “call Graph” profiler. You’ll need to check your system’s documentation (e.g. man gprof) for exact instructions on getting gprof to work, but usually it just involves compiling and linking with -pg, running your program, and doing gprof gmon.out > oopack.

Here’s a 300K sample of output from gprof on the Dec Alpha if you want to take a look at it. This particular report is from a run of AOLServer 2.2.1 which involved fetching index.html 53,623 times.  The links that follow go to anchors in that 300K sample.  What was I wanting to profile?  I wanted a gut check to make sure that life in the server was sane, and if there were any obvious bottlenecks that maybe I could address if I had the time.  The test was to fetch index.html over and over again. In this case, around 53,000 times

There’s 4 parts to gprof output:

  • Built-in documentation: Short form of everything here, and more.
  • Call-graph: Each function, who called it, whom it called, and how many times said calling happened.
  • Flat profile How many times each function got called, the total times involved, sorted by time consumed.
  • Index: Cross-reference of function names and gprof identification numbers numbers.

I go to the flat profile section when I first start looking at gprof output. The big time consumers are usually pretty obvious. You’ll notice that each function has a [number] after it. You can search on that number throughout the file to see who called that function and what functions that function calls. Emacs incremental search is really nice for bouncing around the file like this.

Here you can see that DString is a big time gobbler:

  %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name
 17.7       3.72     3.72 13786208     0.00     0.00  Ns_DStringNAppend [8]
  6.1       5.00     1.28   107276     0.01     0.03  MakePath [10]
  2.9       5.60     0.60  1555972     0.00     0.00  Ns_DStringFree [35]
  2.7       6.18     0.58  1555965     0.00     0.00  Ns_DStringInit [36]
  2.3       6.67     0.49  1507858     0.00     0.00  ns_realloc [40]

Out of 21.05 seconds of total clock time, Ns_DStringNAppend consumed about 4 seconds, or about 18% of the time in and of itself. It was called 13 million times.

MakePath consumed one and a half seconds itself, and its children consumed three and a half seconds. At least one individual call to this consumed 0.01, and at least one individual call took a total of 0.03 seconds in MakePath and its children.

Handy tip – the function numbers in brackets are approximately sorted by time consumption, so a function with a [low number] will generally be more interesting than one with a [high number].

Now that you know that Ns_DStringNAppend is called a bunch of times, this could be a useful target for optimization, I’d look at its entry in the call graph section.

Before doing that, just for illustration, take a look at AllocateCa [33] since it has all of the interesting pieces of the call graph in a more compact size:

                0.04        0.18   53622/160866      Ns_CacheNewEntry [62]
                0.04        0.18   53622/160866      Ns_CacheDoStat [58]
                0.04        0.18   53622/160866      Ns_CacheLockURL [64]
[33]     3.0    0.11        0.53  160866         AllocateCa [33]
                0.16        0.17  160866/321890      Ns_DStringVarAppend [30]
                0.06        0.00  160866/1555972     Ns_DStringFree [35]
                0.06        0.00  160866/1555965     Ns_DStringInit [36]
                0.04        0.00  160866/1341534     Ns_LockMutex [43]
                0.03        0.00  160866/1341534     Ns_UnlockMutex [53]

The entries above AllocateCa [33] are the functions that call AllocateCa. The entries below that are the functions that AllocateCa calls. There are two numbers separated by a slash: the first number is the number of calls that the function has made, while the second number is the total number of invocations of that function.

In other words, for 160866/321890 Ns_DStringVarAppend [30], AllocateCa called Ns_DStringVarAppend 160866 times. Across all of AOLServer, Ns_DStringVarAppend was called 321890 times.

Similarly, for 53622/160866 Ns_CacheNewEntry [62], means that Ns_CacheNewEntry called AllocateCa 53622 times, and AllocateCa was called 160866 times total.

So, just by looking at this snippet, you know that the three Ns_Cache functions each call AllocateCa about once per serving of index.html, and that AllocateCa makes a single call to Ns_DStringVarAppend, Ns_DStringFree, etc… each time. What’s also interesting to note is that someone is calling Ns_DStringFree more than Ns_DStringInit. This may be (or may not) be a bug in AOLServer. You can go see Ns_DStringInit and Ns_DStringFree yourself and track down who the culprit is.

The floating “3.0″ on the left is the percent of total time that the function consumed. The two columns of numbers are the amount of time (in seconds) that the function consumed itself (AllocateCa took 0.11 seconds of time total to run its own code) and the amount of time in the function’s children (0.53 seconds were spent in its children)

Getting back to real analysis of DStringNAppend, you can see that MakePath made 50% of the Ns_DStringNAppend calls. Since you know that there were 53623 fetches of index.html, that means that for each page, MakePath was called twice, and for each call to MakePath, Ns_DStringNAppend was called 64 times.

If one call to MakePath could be elided (since it’s getting called twice), or if fewer than 64 Ns_DStringNAppends could be done per call, we could see a performance boost.

Just browsing the gprof output can be an illuminating exercise. If you have a gut feeling that a particular function is a hot spot (say, Ns_LockMutex [43]), you can see the call graph for that function, see if it’s consuming lots of time, or if it’s being called a whole bunch.  Here it was called 1,341,534 times, or about 25 times per page serve. Maybe that’s high.  Maybe that’s right.  Sometimes a suspected culprit isn’t there, or you find a surprising time waster.

Because this sample gprof output was done on a Dec Alpha system, there was some suckage involved, such as no explicit time recorded for system calls. So we don’t know if, for example, select() blocked for a long time on each call.

 

April 19, 2011

Learning iPhone Programming

Filed under: Big Nerd Ranch, cocoaheads, programming, Questions From Friends — Mark Dalrymple @ 1:20 pm

D31 2840 1

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.

There are a number of video courses available. Stanford CS 193P iPhone Application Development is online. There is another set of materials from the Rose-Hulmn Institute of Technology for their CSSE490: iOS SDK Programming class.  Also, check the comments here, with some links to videos courtesy of Richard Smiley.

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 SDK by 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 RefresherLearn 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.

April 3, 2011

My first professional bug

Filed under: history, programming, Random, Visix — Mark Dalrymple @ 8:23 pm

Clearning with rooking grass

Mike Ash’s recent Friday Q&A about signals mentioned SIGWINCH, the hearing of which always sends me down memory lane.  My first professional bug was centered around SIGWINCH.  By “professional bug”, I mean a bug that someone paid me actual money to fix during a period of employment.

I went to work for a company called Visix straight out of college in the early 90′s, which at the time sold a product called Looking Glass, a file browser much like the Macintosh Finder but for Unix.  Eventually Looking Glass would become the Caldera Linux desktop.  Looking Glass supported the major graphical windowing systems of the time: X11, Intergraph’s Environ V, and Sun’s SunView.  The image at the top of this posting is the only screen shot I could find of the version of Looking Glass I worked on running on SunView.  Notice the awesome desktop widgets at the top.  That was typical SunView style, so Looking Glass was pure awesome eye candy in comparison.

I was hired for the tech support team, and our duties were phone support (typically debugging network configurations and X server font paths) and porting Looking Glass to other platforms.  Being the Lo Mein on the totem pole I got given the old platform nobody wanted to touch any more: SunView.

SunOS 4.1.X had just come out, and Looking Glass would hang randomly.  It worked fine on 4.0.3.  My job was to find and fix this hang.  This was my first introduction to a lot of things: C, unix systems, windowing systems, navigating large code bases, conditional compilation, debuggers, vendor documentation that wasn’t from Apple, working in a company, and so on.  Luckily the SunView version didn’t sell terribly well any more because everyone was moving to X11, but there were a couple of customers bitten by this problem.

So what is SunView?  SunView is a windowing system: different programs run displaying graphical output into a window.  Nowadays that’s commonplace, but back when SunView came out it was pretty cool.  SunView was one of the earlier windowing systems,so it had a bunch of peculiarities: the biggest was that each window on the screen was represented by an honest-to-god kernel device.  /dev/wnd5 is a window, as would be /dev/wnd12.  There were a finite number of these window devices, so once the system ran out of windows you couldn’t open any more.

There was a definite assumption of “one window to one process” in SunView.  Your window was your only playground.  Looking Glass was different because it could open multiple windows.  Because of the finite number of windows available system-wide, we had to create the alert that said “You can’t open any more windows because you’re out of windows” at launch time, thereby consuming a precious window resource, and hide it offscreen.  It was the only way we could reliably tell users why they couldn’t open any more windows.  Glad I wasn’t the one that had to make this work in the first place.  I was just fixing Legacy Code.

The other peculiarity is that you never got window events.  Even in the 1.0 version of the Macintosh toolbox you could easily figure out if the user dragged the window, or resized it, or changed its stacking order.  In SunView you just got a signal. SIGWINCH, for WINdow CHange, and hence the memory-lane trigger.  The user moved a window?  SIGWINCH.  The user resized it?  SIGWINCH.  The user changed the z-order?  SIGWINCH.

With just one window that’s not too bad.  Just query your only window for its current size.  For us, though, we had to cache every window’s location, size, and stacking order.  Upon receipt of a SIGWINCH we would walk all of our windows and compare the new values to the cached version.  If something interesting changed we would need to do the work of laying out the window’s contents.

So, back to my bug.  It took me a solid month to fix.  All this time I thought I was a failure and was worried I’d get fired.  That would be embarrassing. It took so long to fix because it was part time work in amongst my other responsibilities, and also because it was difficult to reproduce.  Spastic clicking and dragging could make it lock up, but not reliably.  Using the debugger was pointless – a 4 meg Sun 3/50 swapped for two hours as dbx tried to load Looking Glass.  I ended up using a lot of caveman debugging.

Event queues

The application event architecture we used is shown right up there.  Each window had an event queue (remember that one window to one process assumption) that held all of the mouse and keyboard events.  Upon receipt of new events (I forget if we got a signal for that, or if some file descriptor became readable), we would walk our windows: read each event, handle it, then move on to the next window.

I was getting some printouts, though, showing an window receiving mouse-downs and mouse-drags, but no mouse-up.  Occasionally I would see a mouse-up, with no mouse-downs.  Ah-ha!  The mouse-up was being delivered to the wrong window’s event queue, probably due to some race condition down in the system that didn’t notice the current window changed during the drag. The fix was easy once I found it : just merge the events from all the windows first, and then process them.  Happiness and light.

It was then I learned how expensive malloc is.  I malloc’d and free’d event structures, but performance was dog-slow, especially during mouse drags.  Caching the structures made life fast again.

Memories like these make me so happy with the cool tech we get to play with these days.

January 20, 2011

Learning iPhone in Pittsburgh

Filed under: cocoaheads, iPhone, programming — Mark Dalrymple @ 7:35 pm

iPhone made out of cup cakesThe Pittsburgh CocoaHeads (where it all started) are going to be working through the new edition of the Dave Mark / Jeff Lamarche / Jack Nutting iPhone book as a group (ebook available today! woo!). Our regular monthly meetings will have a kick-off presentation on what to expect the next month. We figure a chapter a week is a good pace for folks with busy lifestyles.

A couple of us are making ourselves available for “office hours” if folks have questions / get stuck. Huge gumption traps for beginners are compiler errors and basic memory management, things that programmers with more experience can just glance at and know exactly what’s wrong. We’re hoping this solves the “stall-out half-way through” problem many people have picking up new technology as a hobby.

I had the pleasure of being the Tech Reviewer for this updated edition of Beginning iPhone4 Development. There’s a lot of good cool new stuff in there. During the course of discussions with Apress about acquiring the book in time for our launch, they’ve made a CocoaHeads discount code good for 25% off Mac/Phone ebook titles until the end of March : APRESSCOCOAHEADS2011, when you get it from the Apress store. There’s also a discount for folks who already have the iPhone3 version of the book, but I don’t know if they stack.

More info is available at http://bit.ly/pgh-iphone, especially if you’re in the Pittsburgh area. Come join us! Folks outside of Pittsburgh are welcome to do the same thing. Feel free to use the monthly kick-off slides, which I’ll be putting up at http://borkware.com/cocoaheads as we progress into the year.

October 29, 2010

Benzado: How to Learn to Program in 2010

Filed under: programming, Random — Mark Dalrymple @ 10:39 pm

My bud Ben Ragheb wrote a blurb on learning to program in 2010.  I too started with the 8-bit personal computers of the 80s and typed in games from books and magazines, so I’m usually at a loss when someone asks me how to learn to program.  Usually I point them at the browser and mumble “Javascript”, then run away when they’re not looking.

 

September 10, 2010

QFF: Where’s it live?

Filed under: programming, Questions From Friends — Mark Dalrymple @ 8:52 pm

Friend asked on AIM:

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:
memory.png

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

So that’s a leak

Yep!

September 6, 2010

Block Retain Cycles

Filed under: amosxp, programming — Mark Dalrymple @ 10:37 pm

So I’ve seen in a couple of places where you can get retain cycles with Objective-C blocks, and then have to do some contortions to get a __block-storage-class self pointer that won’t be auto-retained.

But I couldn’t find a simple example to demonstrate the problem, and I want to verify the problem before it gets cast into dead trees or implanted into student’s minds.

So here is minimal example. First is a typedef for a block pointer, and a simple object that holds on to the block:

// Just a simple block pointer that asks for nothing and gives nothing.
typedef void (^BlockHead)(void);

// The leaky object.
@interface Leakzor : NSObject {
    NSString *string;
    BlockHead blockhead;
}

// Print |string|.
- (void) funk;

@end // Leakzor

This will leak the object and the block due to the retain cycle:

- (id) init {
    if ((self = [super init])) {
        string = @"snork";

        // |string| is the same as self->string, so |self| is retained.
        blockhead = Block_copy(^{
                NSLog (@"string is %@", string);
            });
    }
    return self;
} // init

If you compile blockcycle with -DRETAIN_CYCLE=1 you won’t see the dealloc NSLog. Why?

blockhead has caused self to be retained. self won’t be released until blockhead is cleaned up in -dealloc. But -dealloc won’t get called because self is still retained by the block. This is a classic retain cycle.

So how to fix it? With these hoops:

        // |blockSelf| is __block scope, so won't be auto-retained
        __block Leakzor *blockSelf = self;
        blockhead = Block_copy(^{
                NSLog (@"string is %@", blockSelf->string);
            });

So now I access string by using the self pointer, but in the shape of a __block-storage-class local variable. This doesn’t have the retain behavior that ordinary variable capture has.

Does this mean that I’m going to be peppering every block that refers to self, directly or indirectly, with this stuff? Nope. But it’s something to keep in mind, especially if you’re making a copy of a block and then dealing with its cleanup in -dealloc (vs some kind of good-bye kiss method).

July 22, 2010

QFF: Kitchen MVC, part 1

Filed under: programming, Questions From Friends — Mark Dalrymple @ 2:08 pm

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:

mvc-1.png

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

mvc-2.png

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:

mvc-3.png

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:

mvc-4.png

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?

That’s in part 2, attack of the code.

July 15, 2010

QFF: id and NSFastEnumeration

Filed under: programming, Questions From Friends — Mark Dalrymple @ 2:48 pm

Do I remember correctly that id is a pointer, like a void*?

Yep. It’s a pointer to an objective-C object, but not necessarily an NSObject.

So, id* is a pointer to a pointer?

Yep. Like a void**.

I’m looking at the fast enumeration protocol

I was wondering where this was coming from :-)

- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState *) state
                                   objects: (id *) stackbuf
                                     count: (NSUInteger) len;

So it’s expecting you to return an array of object pointers?

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:

typedef struct {
    unsigned long state;
    id *itemsPtr;
    unsigned long *mutationsPtr;
    unsigned long extra[5];
} NSFastEnumerationState;

July 14, 2010

QFF: NSDictionary and Autorelease

Filed under: programming, Questions From Friends — Mark Dalrymple @ 2:36 pm

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?

NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
NSMutableDictionary *dict = [NSMutableDictionary dictionary];

Nothing really.

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.

September 7, 2009

VoodooPad and Subversion

Filed under: programming, Random, VoodooPad — Mark Dalrymple @ 2:55 pm

Yeah, Git and Hg are the new hotness, but for some projects I’m still using subversion.

A also like keeping my project documentation in VoodooPad. By keeping a narrative of development in an ever-growing VP, I can go back and figure out where certain “design” “decisions” came from that are currently causing me problems. Not that it ever happens to me. *cough*.

Anyway, I’m moving into a new 13″ MacBookPro (sweet sweet little machine), and I’m taking the nuke-from-orbit approach: only installing software and data files on-demand. So now I need to be able to commit VoodooPad doc changes. This is complicated by VP docs being a bundle with files coming and going as the file is edited.

VooDooPad has nice Script Plugin support, including some sample LUA scripts. Oooh! “Commit changes to subversion”. Perfect!

Getting it set up correctly isn’t 100% obvious – here’s how I do it:

  1. Snarf the “Commit changes to subversion” code” and paste it into a new file living at.
    ~/Library/Application Support/VoodooPad/Script PlugIns/Svn Commit.lua
  2. Subversion now lives in /usr/bin, so edit the /usr/local/bin references accordingly. Here’s my version:
    --[[
    VPLanguage = lua
    VPScriptMenuTitle = Subversion Commit
    VPEndConfig
    ]]
    -- we assume subversion is located in /usr/bin/svn
     
    posix.chdir(document:fileName())
     
    -- add new files
    os.execute("/usr/bin/svn st | " ..
    	       "/usr/bin/grep '^\?' | " ..
    	       "/usr/bin/sed -e 's/\?[ ]*//g' | " ..
    	       "/usr/bin/xargs /usr/bin/svn add")
     
    -- clean up deleted pages
    os.execute("/usr/bin/svn st | " ..
    	       "/usr/bin/grep '^\!' | " ..
    	       "/usr/bin/sed -e 's/\![ ]*//g' | " ..
    	       "/usr/bin/xargs /usr/bin/svn rm")
     
    os.execute("/usr/bin/svn ci -m'auto commit'")
    os.execute("/usr/bin/svn st")
    vpconsole("Commit complete.")
    

  3. Set up your favorite form of passwordless access. I’ve been using ssh’s authorized keys: passwordless access quickie.
  4. Restart VoodooPad to get the new menu item.
  5. Make changes, and no longer fear commitment.

September 5, 2009

AppEngine Launcher

Filed under: GOOG, programming, work — Mark Dalrymple @ 12:55 pm

One of the cool things about working at the GOOG is you can spend 20% of your time on projects unrelated your usual work. It’s the responsibility of each engineer to actually find or make a project, and to take the time to do it. But it’s really nice having the opportunity.

Over the last 9 months or so, I’ve thrown in my 20% time on the App Engine Launcher for Windows. Even though it says Windows, I did most of my work on the Mac, since the project is in Python and uses wxWidgets. Because of this, the Launcher works on Linux too.

And now it’s shipping. Woo! And it’s open sourced.

What is the Launcher? It’s a little dashboard where you can create new App Engine projects, run them locally, look at the logs, and deploy to appspot.com.

So, why this particular project? Good question, since I haven’t done much with AppEngine, outside of a small Photo Software Quickies database, similar to the Borkware Quickies. There were two reasons.

The first was to keep working on a project with the Launcher tech lead, John Grabowski. I worked with him on a previous project and had a lot of fun. If you ever get a chance to hear him talking about brewing beer or raising his six kids, you should.

The second was to have an excuse to expand my horizons. I’ve never really used Python before, and I need an actual project to work on before I really learn something. Here was a project that folks have been wanting and I could learn a new language and toolkit. Perfect fit. I absorbed a huge amount about Python, particularly during the code reviews from our Python expert Dave Symonds in Australia. Every code review I had to fix stuff, but I learned a bunch.

So now the technical take-aways.

Python is a nice language. self.There() are a self.few() annoying self.things() about self.python() self.that() self.KindOf() self.drove_me_nuts(). Whitespace indentation wasn’t one of them. I still program it with a C accent (and my C still has a Pascal accent), but through code review I fixed the most egregious anachronisms.

As a cross-platform toolkit, Wx is adequate. If I *had* to use a cross-platform toolkit, I’d use Qt, and also look at CocoaTron. And then weep for the demise of Galaxy. Wx actually looks and behaves well on Windows and Linux, but it doesn’t even reach the Uncanny Valley on the Mac.

We decided to use wxglade for creating the user interface components. That was probably the only big mistake of the project. It was nearly unusable on the Mac, frequently neglecting to save changes. Sometimes it took 5 edit/ok/save/generate-code cycles for menu bar edits to actually stick. Oh, and it’s a code generator. We hateses code generators, my precious. For some reason, wxglade kept on trying to make the main window huge. And finally, the code generator occasionally decides it wants to generate the same code twice. It doesn’t break anything, but still messy.

So, go check out the Launcher, now included with the App Engine SDK for Windows and Linux. There is a Mac version (which I didn’t work on) which has been shipping with the App Engine SDK for Mac for awhile.

August 13, 2009

Easy Nested-Object Selection in IB

Filed under: programming — Mark Dalrymple @ 10:42 am

Thanks to Marcus Zarra‘s excellent Core Data book for this little tidbit.

Hate Interface Builder when dealing with table views, having to clicky-clicky to get down to the table column, and frequently clicking the Wrong Thing and having to start over?

If you hold down the shift key while performing the contextual menu gesture of your choice, you get a menu that lets you go straight to your intended victim:

Picture 30.png

March 12, 2008

Making Command-Line Tools

Filed under: iPhone, LoC, programming — Mark Dalrymple @ 8:45 pm

Just in case you’re reading Learn Objective-C on the Macintosh, and you’re wanting to make a “Foundation Command-Line Utility” project in the might (or might not) be new Xcode which might (or might not) be associated with the latest iPhone excitement, you’ll probably want to look under “Command Line Utility” on the sidebar, and choose “Foundation Tool” from the project picker. They may (or may not) have moved it from previous Xcode versions. Or not. You didn’t hear it from me,

March 11, 2008

Learn Objective-C… on the iPhone?

Filed under: iPhone, LoC, programming — Mark Dalrymple @ 3:06 pm

I usually don’t like to Pimp my own Warez, but Sir Daniel Punkass pointed out to me that Learn Objective-C on the Macintosh is quite applicable to iPhone development, especially for folks who don’t already know Objective-C. Sometimes I’m a bit clueless.

LoC is an introductory book, but assumes you know C (it’s officially the follow-on to Learn C On the Macintosh). It covers a lot of the basic stuff you need in Cloud-Cocoa Land – especially memory management, which we go over a lot in the latter half of the book, since memory management is the place that many Cocoa programmers have problems.

We tried to make it as non-boring as possible, so I think even experienced programmers can get something out of it. From a twitter in response to Mr. Punkass, Diego wrote “started on the book and it’s very good. straight to the point and doesn’t linger on topics. which i like. thanks for the tip” (Thanks Diego!)

On the down-side, it doesn’t cover the properties syntax, or the new fast enumeration syntax, but once you have the basics of the language under your belt, you should be able to pick those up quickly.

March 9, 2008

OpenGL ES

Filed under: programming — Mark Dalrymple @ 1:06 pm

Want to learn more about OpenGL ES? http://www.khronos.org/opengles/ has some information. The OpenGL ES 1.1 specs would probably be of the most interest.

January 20, 2008

Release In Order

Filed under: programming — Mark Dalrymple @ 4:51 pm

My cow-orker, Mike Morton, gave me a little bit of advice over a year ago that’s proven to be incredibly useful: “In your -dealloc, release objects in the same order they’re listed in the @interface“. This makes it really easy to double-check your work and make sure you’re releasing everything you need to. It also makes maintenance easier: skim down your -dealloc and compare to your @interface before you land your code.

October 31, 2007

Exploring Leopard with DTrace

Filed under: programming, work — Mark Dalrymple @ 4:39 pm

My friend and cow-orker Greg Miller has a piece published at MacTech: Exploring Leopard With DTrace.

DTrace is cool. DTrace is awesome. Go read this.

October 26, 2007

ZeroLink, Rest in Pieces

Filed under: irc, programming — Mark Dalrymple @ 11:28 pm

6FF1A549-451F-4BCB-9EB5-3317786D19E3.jpg

One thing that made me happy, and was greeted with applause at WWDC, was the news that ZeroLink is gone in Leopard. The linker is now fast enough to make ZeroLink unnecessary.

So what was so bad about ZeroLink? The first problem wasn’t actually ZeroLink’s fault – it was Apple making ZeroLink on by default for new Xcode projects. A common refrain heard from new Mac programmers was “I made a Cool Little Cocoa App, sent it to a friend it won’t work for him. What’s wrong?” ZeroLink.

ZeroLink performed its magic by demand-loading object files, and those object files weren’t included in the application bundle until several Xcode revisions later. So sending an App to a friend (or a reviewer, or a cow-orker) would mean sending them a broken app. Then the programmer would ask for help on a mailing list or IRC, get told to turn of ZeroLink, and then rebuild and re-send. In fact, the Feenode #macdev FAQ has a special section just for ZeroLink.

This was embarrassing and demoralizing, especially for someone new to the platform. New, small projects didn’t benefit from ZeroLink anyway, and you have to have a pretty large program before the time savings is noticeable. Someone with a project that big will have someone intimate with Xcode who would know about ZeroLink, so need to have it on by default.

The second problem was that ZeroLink introduced instability, with its frequent refrain being “I’m getting weird crashes”, which are fixed after turning off zero link. I got paid for a full day’s consulting tracking down a strange C++ operator new overload. The daily smoke test built and ran great, but development versions crashed and burned in weird places. We finally tracked the main difference between the developer builds and the automated builds: ZeroLink. Turned it off, rebuilt, and life was happy ever after. This particular app (which was freaking huge) was broken down into lots of frameworks, so link time wasn’t that much longer than with ZeroLink. (Because of this framework breakdown, I was able to pull some command-line tricks to prevent unnecessary recompilation of other parts of the system, and greatly reduced my turnaround time on a TiBook500 vs the G5-weilding full-timers, but that’s a story for another day.)

Good bye ZeroLink.

October 4, 2007

Pittsburgh CocoaHeads

Filed under: cocoaheads, programming — Mark Dalrymple @ 10:03 am

FDF2963A-3D56-4EE3-8A46-74A6D6ACA7FB.jpg

After about a year off, Pittsburgh Cocoaheads is going to be starting up again. Second thursday of the month, 7:30 – 9:30 PM, on the CMU campus (Newell-Simon Hall. Room 3000 or 3001. There will be signs pointing the way)

And for folks who don’t know about CocoaHeads, it’s an international Mac Programmer’s group. Pretty much an excuse for Mac programmers to congregate and geek out. Right now we have 20ish chapters in seven countries, two hemispheres, and four continents. Check out CocoaHeads.org for a chapter near you. If there is no local chapter, or if your local chapter hasn’t met in awhile, feel free to drop us a line and become an organizer.

CocoaHeads started in Pittsburgh several years ago when AgentM and I decided to start a Mac programmer’s group because there was nothing in the area. He came up with the name and the logo, and did a lot of evangelizing in the early days. I’m glad AgentM picked the name : I would have come up with something horrible like “Western Pennsylvania Mac Programmer’s Geeking Out And Food Eating Society”, which doesn’t quite have the groovy ring of “CocoaHeads”

September 29, 2007

Don’t Forget VoodooPad

Filed under: amosxp, programming, Random, work — Mark Dalrymple @ 3:57 pm

With all of the love and attention that Flying Meat’s Acorn is receiving, I figured I would remind folks about VoodooPad.

VoodooPad is a personal Wiki that lets you write stuff and link things around. When it sees words in CamelCapsStyle, it automatically turns it into a link to a new page where you can write more stuff. All pretty standard wiki stuff. It uses the OS X text engine so it has all of the standard word processing features you’ve come to expect, including stuff like tables and lists. This is especially nice because I get a lot of my emacs key bindings along for free. Muscle memory is a wonderful, wonderful thing.

Screen Capture of VoodooPad pro

There are a couple of things I love about VoodooPad : it gets out of my way. I type, I link, I paste in graphics. Gus has obviously paid a lot of attention to the fine details and the app just gets out of my way. It is also very stable. I don’t remember when my last crash was. It just works. Just about every Leopard update makes SnapZ pro freak out and I have to get get new license keys (and then usually something fails on the server side, and takes 20 minutes of dinking around to get a license). Omnigrackle‘s layers get confused and the PDF export dialog has a bug that makes it easy to corrupt your document. Mail.app regularly crashes. But VoodooPad just keeps on chugging along. Oh, and it’s fast, too.

Some folks I know put everything into a single VoodooPad document and use it to store their life (or at least their brains). I typically have one VoodooPad document per project, which usually fall int into one of three broad categories:

Design Document : I have one where I keep my design notes for the Extreme Cross Stitch Design software I’m working on for the Spousal Overunit. I dump figures from OmniGrackle in there, and use class names as the currency of links. This makes it very easy to capture my thinking about the specifics of individual classes, as well as highlighting the interactions between classes. Sometimes I can go for a month or two between working on the App, so having all this stuff handy and interlinked makes it easy to reload my mental state. My winning IronCoder entry included a VoodooPad design document with all sorts of notes. (The entry was Race Against Time, if you’re really bored)

Data Dump and Organizer : I have another one where I keep all my notes, to-dos, transcriptions, and copies of interesting emails for the next edition of AMOSXP. You can see a screenie for this is over to the right. I blort in anything and everything I think might be interesting for the next edition. As I start chewing up a chapter, I have ready access to stuff to consider for exclusion (and stuff to nuke). Sometimes one topic (say an extension to a favorite object-oriented language) is too big for one chapter, so something like its automated memory management technique would make better sense living in the Memory chapter. So I can easily make a note in MemoryChap to say “go look over InThisSetOfNotes for these aspects of rubbish aggregation that would be interesting to talk about here”

Debugging Aid : For projects where I tend to do more debugging than design, I have a VoodooPad document that keeps my debugging notes. Usually for each non-trivial problem there’s a page with a dialog with myself. “So What’s the Problem Fool? Oh, Google Kipple is crashing when you frobulate the giznat. Does it happen all the time? No, just on the second launch. Maybe it’s the SpicyPonyHead user preference Hrm, could be” The dialog format lets me focus my thoughts by making explicit what the next useful piece of information might be, and it makes for easier reading when I need to revisit a bug or if I have to put it down for awhile and return to it later. The linky nature of a wiki makes it easy to put in different branches of investigation and let me revisit what I originally thought was a dead end, but might actually be the path to figuring out the real problem. Because Cocoa class names are CamelCapStyle, class names in stack trace become links. Ppaste in a stack trace and then link out to a class to jot down some relevant notes.

I’m a fan. Check it out.

September 13, 2007

C Callbacks in ObjC

Filed under: amosxp, irc, programming — Mark Dalrymple @ 11:23 am

It’s interesting to see common subjects come up in the IRC channels. When someone unfamiliar joins and asks the question “how do I put a method into a function pointer?”, 9 times out of 10 they’re actually wanting to use Cocoa with an existing C API that uses callbacks. A much better question would be “I’m using a C API that uses callbacks with Cocoa, how do I make it work?”

The Answer

You can’t use Objective-C methods as callbacks. Stop trying, you’ll just make yourself angrier. You have to bounce off of a regular C function, and use any “userData” or “info” mechanism in your C API to pass a pointer to your object.

So assuming you have a call SetDrawingCallback, which takes a function, but you actually want to draw using your objecty-goodness OblateSphereoid object, you would do something like this:

BWOblateSphereoid *egg = [[BWOblateSphereoid alloc] init];
 
SetDrawingCallback (drawingContext, /* context that wants to draw */
                    drawEggThunk, /* the function that the context will call */
                    egg);  /* arbitrary userData pointer */

Then in your callback function:

void drawEggThunk (DrawingContext *context, Rect areaToDraw, void *userData)
{
    BWOblateSphereoid *dealie = (BWOblateSphereoid *)userData;
    [dealie drawAnEggInRect: areaToDraw];
} // drawEggThunk

You are allowed to call Objective-C methods in a C function. You just need to make sure your file is compiled as Objective-C, whether you have a .m extension, or tell Xcode to compile it as Objective-C explicitly. If your callback API doesn’t let you pass in a userData pointer (a rock to hide your data under), you’ll have to put your object into some global location for your C function to find.

If you need to poke inside of the object directly, you can put this function inside of the @implementation block of your class, and then you can access instance variables with the C arrow operator. But that’s kind of naughty, so to preserve your Purity of Essence you should be using method calls on your object. End of Sermon. Here’s the evil:

@implementation OblateSphereoid
 
void drawEggThunk (DrawingContext *context, Rect areaToDraw, void *userData)
{
    BWOblateSphereoid *dealie = (BWOblateSphereoid *)userData;
    dealie->_frognatz = [NSColor plaidColor];
    // and more stuff.
} // drawEggThunk

...
@end // OblateSphereoid

Why?

So why can’t you just (somehow) get the address of -drawAnEggInRect: for the BWOblateSphereoid class and pass that for the drawing callback? The answer is a secret. Two of them, in fact.

When you use brackets in Objective-C to send a message to an object, the compiler is actually generating a call to the C function objc_msgSend (or to one of its variants, but let’s keep it simple):

id objc_msgSend(id self, SEL op, ...);

So something like [egg drawAnEggInRect: someRect] turns into:

objc_msgSend (egg, @selector(drawAnEggInRect:), someRect);

Which then calls drawAnEggInRect:, which under the covers boils down to something like this:

void drawAnEggInRect(id self, SEL selector, Rect someRect) ...

self and the selector are passed in as secret hidden parameters, and then any arguments for the method follow them. This is why you can’t just use the address for a method’s code in a C callback API. The library code invoking the callback will be wanting to put its own stuff in the first couple of arguments, which will cause all sorts of nifty explosions when Objective-C starts interpreting those as object pointers and selectors.

Older Posts »

The Shocking Blue Green Theme. Create a free website or blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.