Archive for the 'Apple' Category

The iPad & Reading (Free Books, too!)

Sunday, April 11th, 2010

Update:I’m keeping a list of ebook publishers/sources for which I’ve found inFeel free to send me suggestions. This is, by no means, a complete list — I’m just taking notes as my OCD-compulsive nature kicks in and I build up a huge set of books to read.

  • The Baen Free Library contains quite an amazing selection of donationware ebooks from many well known science fiction and fantasy authors.
  • Feedbooks contains a ton of public domain and original content as they are also a publisher of ebooks. Their blog is pretty interesting, too.
  • A one-off; Charlie Stross’s Accelerando comes highly recommended.
  • In the meta-category; a weblog post claiming to point to the “top 20 websites for DRM-free Sci-Fi Books”.
  • This list is impressive and also leads to cheap sources for ebooks, too. I’m perfectly happy paying for ebooks (just like real books), though I’m not at all happy about paying more than the paperback price for an older book.
  • Tor books — publishers of Jordan’s Wheel of Time series — has embraced ebooks to a large degree.

iBooks-SciFi.PNG

I know lots of people that have picked up iPads — no surprises there. What is surprising is that just about everyone has something for which their reaction is “the iPad changes everything”.

I have several of those, but — at the moment — the biggest is reading. I used to read tons and tons of books, but gradually tapered off because I carrying around a couple of books was a pain in the ass and, for vacations, I would need to take up to a dozen, depending on duration.

That and, frankly, it has been bloody obvious for years that an e-book read that is “good enough” would provide a portable library and a decent reading experience. The Kindle was almost the one, but having 40% of the front surface area covered by a keyboard seemed like a complete waste to me. I did, however, use the Kindle app on the iPhone to read a couple of books — good, but not great.

I find iBooks to be a wonderful reading experience. Easy on the eyes, very nice user interface and — with the versatility of the iPad — I can read Kindle books, and do a myriad other things on the device. Haven’t spent much time with the Kindle app, but if it is like the iPhone, it’ll be just fine, too!

I, however, am a cheapskate. I haven’t quite brought myself to drop money on books. Fortunately, there is a large number of freely available books in both the iTunes and Kindle stores.

With a bit of hunting, I have also hit upon a treasure trove of mostly Science Fiction and Fantasy — my favorite genres — books! In particular, Baen Books made available a large number of their books in many formats! In particular, you can find a list of the participating authors, click through to their titles, then select the EPUB/Nook/Stanza Format on the download page.

Note that the books have covers as in the picture on the left, but the cover art doesn’t show up in the iBooks application on the iPad.

I donated $51 in return for a ton of books.

Posted in Apple, Books, Technology | 5 Comments »

Geotagging Photos With Aperture & QStarz BT-1300S

Thursday, March 11th, 2010

With the release of Aperture 3, geotagging photos is now an integral part of the application’s workflow. Aperture grew the Faces & Places features like iPhotos!

In particular, the Places feature allows you to import GPS data from iPhone photos or from GPS data captured by pretty much any device that can spew a standard GPX format data file.

ImportFromiPhone.png

Tagging from the iPhone is straightforward. With the iPhone connected to your computer, go to Places in Aperture and then select Import from iPhone Photos…. Aperture will then display all the photos on your iPhone that have GPS metadata and you can pick the photos from which the GPS data is to be imported. Once picked, Aperture will apply the GPS data to photos taken near the same time as the imported data.

However, one issue with the iPhone is that it really isn’t a terribly good GPS logging device. Using it as one eats the battery and the data generated often has holes. And, because the iPhone uses A-GPS (GPS assisted by cellular signal), it doesn’t work at all when hiking in areas without cell signal. Apparently, I’m mistaken about A-GPS — it should fall back to regular GPS behavior. My experience, though, is that the iPhone just isn’t a terribly good GPS device when it doesn’t have a cell signal and has often been off by miles when in the hinterlands. It works great when on the road or near cities, though.

Read the rest of this entry »

Posted in Industrial Design, Mac OS X, Photography, Technology | 10 Comments »

No, iTunes, I don’t want to listen to holiday music in February….

Monday, February 22nd, 2010

We have a ton of Christmas music — 400 or so tracks, with it growing by about 50-75 tracks each year — that ranges across all genres. It is some awesome stuff; blues, reggae, pop, traditional, you name it…

However, it is music that should only be in the rotation starting December 1st, heavy rotation by about the 15th-20th and then no more from December 26th to the next December 1st.

Of course, iTunes is agnostic and, thus, does not follow my holiday music filtration wishes.

Easy to fix.

  1. On all Christmas/Holiday music, add a grouping of “Holiday” or “Christmas” (or whatever you want).
  2. Create a smart playlist that finds all music in said grouping. Make sure the smart playlist matches unchecked items.
  3. On December 26th, select all, ctrl-click, and select uncheck selection
  4. On Decmber 1st of the next year, select the smart playlist, select all, ctrl-clik, and select check selection

Done. iTunes will not select unchecked songs when constructing genius playlists or when playing through the library on shuffle play. Smart playlists can optionally include checked songs.

Posted in Apple, Software | No Comments »

objc_msgSend() Tour Part 4: Method Lookup & Some Odds and Ends

Thursday, February 4th, 2010

Table of Contents

  1. objc_msgSend() Tour Part 1: The Road Map
  2. objc_msgSend() Tour Part 2: Setting the Stage
  3. objc_msgSend() Tour Part 3: The Fast Path
  4. objc_msgSend() Tour Part 4: Method Lookup & Some Odds and Ends

In the first three parts, I gave an overview, explained a bit of the ABI used by Objective-C, and took a near instruction by instruction tour of what happens on the fast path of Objective-C method dispatch. By fast path, I mean what happens 99.9% of the time; a very fast, no overhead, no function call, no locking, set of instructions that grabs the method implementation from the cache and does a tail-call jump to that implementation.

The slow path is used rarely. As little as once per unique selector invoked per class with a goal of filling the cache such that the slow path is never used again for that selector/class combination. A handful of operations will cause a class’s cache to be flushed; method swizzling, category loading, and the like.

Note that during +initialize, methods won’t always be cached. Yet another reason to not do any real work during +initialize! Read the rest of this entry »

Posted in Mac OS X, Objective-C, Software | 4 Comments »

Using malloc to Debug Memory Misuse in Cocoa

Sunday, January 10th, 2010

Every few months, there is a discussion on cocoa-dev or a question on stackoverflow.com that basically boils down to “I have a leak or over-release and I can’t use Instruments to debug it. Help?”.

Quite often, the questioner can actually use Instruments just fine, but simply lacks the know-how or hasn’t tried in a while and doesn’t realize that Instruments has improved significantly with each release of the developer tools. No, really, Instruments is a fantastic tool and I use it whenever I can; what you see below is for the exceptional case, not the norm.

There are cases where using Instruments is either inconvenient or impractical. Namely, trying to track down an intermittent crasher or trying to gain insight into memory leaks over a long running session will create a prohibitively large dataset for Instruments to process (Instruments allows for much more detailed analysis of the object graph and this analysis loads a lot more data than the tools I’ll demonstrate below).

Thus, it is helpful to be familiar with the rather powerful set of tools available from the command line and within the debugger.

Almost always, you are going to want to enable a bit of additional data via the malloc infrastructure. Have a look at the malloc(3) man page. There is an entire section devoted to ENVIRONMENT variables and there are a handful of extremely useful variables!

First and foremost, you are almost always going to want to use MallocStackLoggingNoCompact. When enabled, malloc stack logging writes the stack trace of every allocation and free event to an efficiently compact binary file in /tmp/ (it used to be in memory and, thus, used to be a great way to exhaust heap. No longer!!). Unfortunately, it doesn’t record the retain and release events, but simply knowing where the object was allocated is generally quite useful (it is generally relatively easy to track down who retained an object once you know which object it is). Under GC, you can set the AUTO_REFERENCE_COUNT_LOGGING and CFRetain/CFRelease events will be logged to the malloc history.

You can then use the malloc_history command line tool to query for all events related to a particular address in memory.

While malloc_history requires that the process still exists, it doesn’t have to be running! If you run your app under gdb, you can still use malloc_history to query the application even when it is stopped in the debugger!

Speaking of gdb, you can use the info malloc command in gdb to query the same information. Under GC, the info gc-roots and info gc-referers commands can be used to interrogate the collector for information about the connectivity of the object graph in your running application.

If you enable zombies via setting the NSZombieEnabled environment variable to YES, the address spewed in the error message when messaging a zombie can be passed directly to malloc_history.

The leaks command line tool scans memory and detects leaks in the form of allocations of memory for which the address to that memory is not stored anywhere else within the application. The leaks tool has been vastly improved in the Snow Leopard release of the Xcode tools; it is much much faster and spits out false positives almost never. It is still possible to have a leak that leaks cannot detect, of course. And, remember, even if you can still reach memory, it is still a total waste if you never use that memory’s contents again!

So, that is a brief summary of the state of command line memory debugging on Mac OS X as of Snow Leopard. Of course, that’s just a bunch of words. How about an example?

Read the rest of this entry »

Posted in Cocoa, Mac OS X, Objective-C | 3 Comments »

objc_msgSend() Tour Part 3: The Fast Path

Friday, December 18th, 2009

Table of Contents

  1. objc_msgSend() Tour Part 1: The Road Map
  2. objc_msgSend() Tour Part 2: Setting the Stage
  3. objc_msgSend() Tour Part 3: The Fast Path
  4. objc_msgSend() Tour Part 4: Method Lookup & Some Odds and Ends

In any case, with the foundation set — with the id of the object to be targeted in %rdi and the selector of the method to be invoked in %rsi — we can jump into objc_msgSend() and understand exactly what happens instruction by instruction. Or more specifically, the compiler issues a call into objc_msgSend() (which sets up a stackframe for objc_msgSend() which, through tail call optimization, turns into the stackframe for the called method) and the method implementation that objc_msgSend() jumps to will issue a ret instruction to unwind the stack back to the original caller’s frame.

It is pretty easy to correlate the disassembly with the comments and code in the original source file. However, if you ever need to step through the messenger (si steps by instruction in gdb), this will be easier to follow as this is closer to the reality during a debug session.

For almost all method dispatches, dispatch takes what is called the “fast path”. That is, objc_msgSend() finds the implementation in the method cache and passes control to the implementation. Since this is the most common path, it is a good opportunity to break the tour of objc_msgSend() into two parts; the fast path and the slow path (with administrivia).

Read the rest of this entry »

Posted in Mac OS X, Objective-C, Software | 6 Comments »

objc_msgSend() Tour Part 2: Setting the Stage

Friday, December 18th, 2009

Table of Contents

  1. objc_msgSend() Tour Part 1: The Road Map
  2. objc_msgSend() Tour Part 2: Setting the Stage
  3. objc_msgSend() Tour Part 3: The Fast Path
  4. objc_msgSend() Tour Part 4: Method Lookup & Some Odds and Ends

Objective-C is, ultimately, a simple set of extensions to C that provide an object oriented coding and runtime model. Objective-C fully embraces C and leverages the C calling ABI throughout. Every method call is really just a C function call with objc_msgSend() acting as the preamble that figures out exactly which C function — which method — to call!

Thus, it is helpful to understand how objc_msgSend() is called and how that relates to C. That is, how does the compiler translate [someObject doSomething: 0x2a] into a call.

What follows is a bit of code that makes a [totally bogus] simple method call followed by the assembly generated.

Code:
@interface NSObject(foo)
- (id) doSomething: (NSUInteger) index;
@end
...
    NSObject *b;
    NSArray *a;
    b = [a doSomething: 0x2a]; // line 11
Assembly:
    .loc 1 11 0
    movq	-16(%rbp), %rdi
    movq	L_OBJC_SELECTOR_REFERENCES_0(%rip), %rsi
    movl	$42, %edx
    call	_objc_msgSend
    movq	%rax, -8(%rbp)

Read the rest of this entry »

Posted in Mac OS X, Objective-C, Software | 4 Comments »

objc_msgSend() Tour Part 1: The Road Map

Friday, December 18th, 2009

What follows (across this and 3 more posts, maybe more) is a rather detailed tour of objc_msgSend() as implemented in Mac OS X 10.6.2. Rather detailed in that every instruction will be explained. Even though it is relatively few instructions, there is a considerable amount of background information that is helpful to understanding the objc_msgSend() instruction stream.

The motivation behind these posts is entirely selfish. I find the best way for me to learn something is to know it well enough to be able to explain any detail to a room full of folks in full-blown student mode.

Table of Contents

  1. objc_msgSend() Tour Part 1: The Road Map
  2. objc_msgSend() Tour Part 2: Setting the Stage
  3. objc_msgSend() Tour Part 3: The Fast Path
  4. objc_msgSend() Tour Part 4: Method Lookup & Some Odds and Ends

Read the rest of this entry »

Posted in Mac OS X, Objective-C, Software | 13 Comments »

DPhyllotaxis

Sunday, October 25th, 2009
Screenalicious - DPhyllotaxis - 200910298 205041.539.png

Ultimately, the whole point of resurrecting my old screensaver code was to finally port DPhyllotaxis to Snow Leopard.

Beyond being, perhaps, the most over-engineered screen saver ever for what ultimately draws colored dots, I wrote this as a sort of virtual flower for my then-girlfriend, now-wife-of-more-than-a-decade, Christine.

The underlying algorithm on this one is based entirely on phyllotaxis and the phyllotactic pattern of growth seen across so much of the plant world. The most well known example being the layout of seeds in a sunflower and that particular form of phyllotaxis is exactly what this screensaver mimics.

The color calculation in this particular screen saver is, frankly, goofy. Every floret — every dot — is actually rendered. The brightness is determined by calculating a color once, grabbing the red component and then calculating the color again using a slightly different algorithm and using the previous red value as the new brightness. Rather silly, but the results are pleasant enough.

Screenalicious - DPhyllotaxis - 200910298 205114.991.png

When I originally wrote this in 1994-ish, it used Display PostScript to do all the drawing. Specifically:

/* this should not be done here */
PSarc(cp.x, cp.y, 15. + (11. * pp.r), 0, 360);
PSgsave();
PSfill();
PSgrestore();
NXSetColor(NX_COLORBLACK);
PSstroke();

I have no idea why, 15 years ago, I thought it important to note that “this should not be done here”. None. So, in the ported code, the comment is gone.

CGFloat floretDiameter = 10. + (11. * pp.r);
CGFloat floretRadius = floretDiameter / 2.;
NSRect floretRect =
    NSMakeRect(cp.x - floretRadius,
    cp.y - floretRadius,
    floretDiameter, floretDiameter);
NSBezierPath *floretPath = [NSBezierPath
    bezierPathWithOvalInRect: floretRect];

[floretPath fill];

[[NSColor blackColor] set];
[floretPath stroke];

There are, of course, many ways to make the above a ton faster. Save for reducing power usage by going a more efficient route, it just doesn’t matter for this particular use case as I already had to slow down the animation rate considerably.

Seems there has been a bit of performance jump between the 25MHZ 68040 this was originally written on and the 2GHZ Core 2 Duo machine I used for the porting work.

Code is in the same repository as the other screen savers. I also tossed a pre-built binary on the server. Only tested on 64-bit Snow Leopard, but it might should also work on 10.5 ppc/i386.

Posted in Entertainment, Mac OS X, Objective-C, Software | No Comments »

+initialize Can Be Executed Multiple Times (+load not so much)

Sunday, September 6th, 2009

Some confusion on StackOverflow led to a massive string of comments. This is a question that comes up often, so here is some google fodder.

In Objective-C, a class can implement +initialize. This method will be invoked the first time the class is touched, prior to any other methods (other than +load).

The documentation says:

The runtime sends initialize to each class in a program exactly one time just before the class, or any class that inherits from it, is sent its first message from within the program.

Which is exactly true. But your +initialize methods can still be executed more than once!

Specifically, if a subclass does not implement +initialize but its superclass does, then that superclass’s +initialize will be invoked once per non-implementing subclass and once for itself.

An example (Foundation Tool, Garbage Collected):

@interface Abstract: NSObject
@end
@implementation Abstract
+ (void) initialize
{
    NSLog(@"Initializing %@", self);
}

+ (void) load
{
    NSLog(@"Loading");
}
@end

@interface Sub : Abstract
@end
@implementation Sub
@end

int main (int argc, const char * argv[]) {
    [Sub class];
    return 0;
}

This will output:

ArgyBargy[3720:903] Loading
ArgyBargy[3720:903] Initializing Abstract
ArgyBargy[3720:903] Initializing Sub

Which is why most +initialize methods are implemented as:

@implementation MyClass
+ (void) initialize
{
    if (self == [MyClass class]) {
        // ... do +init stuff here ...
    }
}
...
@end

Now, categories can seriously screw things up (as usual). Namely, if you implement +initialize in a category, it will override the classes +initialize. However, a category provided +load will not; both the category’s and the class’s +load methods will be invoked.

If you were to add the following category to the Sub/Abstract/NSObject example above:

@interface Abstract(Cat)
@end
@implementation Abstract(Cat)
+ (void) load
{
    NSLog(@"Category +load");
}
+ (void) initialize
{
    NSLog(@"Category +initialize %@", self);
}
@end

The program will spew:

ArgyBargy[3919:903] Loading
ArgyBargy[3919:903] Category +load
ArgyBargy[3919:903] Category +initialize Abstract
ArgyBargy[3919:903] Category +initialize Sub

Keep in mind, as well, that the runtime sends +initialize “in a thread-safe manner”. That implies that there is a lock involved somewhere within which then also implies that you better not block on a lock in your +initialize because whoever is supposed to unlock the lock might end up blocking on +initializes lock.

Or, to put it more bluntly, do not do any heavy lifting in +initialize. Keep it super simple & fast.

For me, +initialize is to be used only as a method of last resort. Well, 2nd to last. Last resort is a constructor attributed function (or +load). Read the rest of this entry »

Posted in Mac OS X, Objective-C, Software | 13 Comments »