NetNewsWire has a feature where it sends me crash logs (if the user clicks the send button) — so I see a fair amount of Flash crashes.
Stuff like this is not at all uncommon:
Thread 9 Crashed: 0 ??? 0000000000 0 + 0 1 ...romedia.Flash Player.plugin 0x183c0795 Flash_EnforceLocalSecurity + 98669 2 ...romedia.Flash Player.plugin 0x180dc962 0x18000000 + 903522 3 ...romedia.Flash Player.plugin 0x180dd081 0x18000000 + 905345 4 ...romedia.Flash Player.plugin 0x180dd7b1 0x18000000 + 907185 5 ...romedia.Flash Player.plugin 0x1838f81c 0x18000000 + 3733532 6 libSystem.B.dylib 0x9061dc55 _pthread_start + 321 7 libSystem.B.dylib 0x9061db12 thread_start + 34
But lately I’m starting to see Silverlight crashes now too.
Thread 8 Crashed: 0 ...microsoft.SilverlightPlugin 0x172e2b3b CMediaElement::Buffering(float) + 303 1 ...microsoft.SilverlightPlugin 0x17625249 0x1729f000 + 3695177 2 ...microsoft.SilverlightPlugin 0x172ecf25 CMFByteStreamOnStream::BeginRead(unsigned char*, unsigned long, IMFAsyncCallback*, IUnknown*) + 493 3 ...microsoft.SilverlightPlugin 0x174264c8 CByteStreamCacheReader2::_BeginCacheItemRead(unsigned long long, int) + 286 4 ...microsoft.SilverlightPlugin 0x174271b9 CByteStreamCacheReader2::BeginCacheRead(IMFAsyncCallback*, IUnknown*) + 297 5 ...microsoft.SilverlightPlugin 0x173efdb8 CASFBytewiseMediaSource::AsyncReadData() + 216 6 ...microsoft.SilverlightPlugin 0x173f02c8 CASFBytewiseMediaSource::DoReadPackets(CASFSourceOperation*) + 94 7 ...microsoft.SilverlightPlugin 0x173f054b CASFBytewiseMediaSource::DispatchOperation(CBaseOperation*) + 83 8 ...microsoft.SilverlightPlugin 0x1745b991 COpQueue::ProcessMarshalledOperations(IMFAsyncResult*) + 175 9 ...microsoft.SilverlightPlugin 0x1765a62b COpQueue::ProcessMarshalledOperationsAsyncCallback::Invoke(IMFAsyncResult*) + 27 10 ...microsoft.SilverlightPlugin 0x17477248 CCompletionPortNT::InvokeCallback(tagMFASYNCRESULT*) + 64 11 ...microsoft.SilverlightPlugin 0x173dc238 CWorkQueue::CThread::ThreadMain() + 164 12 ...ple.CoreServices.CarbonCore 0x94395beb PrivateMPEntryPoint + 56 13 libSystem.B.dylib 0x94f92c55 _pthread_start + 321 14 libSystem.B.dylib 0x94f92b12 thread_start + 34
Etc. (There are a few others.)
I’ve said it before — one of my favorite things about the iPhone is no Flash. I will now add and no SilverlightPlugin.
(I hate when plugins crash my app. The user doesn’t know that it’s something other than my code that’s causing the crash, and it’s cold comfort anyway.)
1. Splitview resizing
Open Mail. Resize the window via the resize-thing at the bottom right corner of the window.
Note that the width of the source list (mailboxes and things) on the left stays at a constant width as you resize the window. (Same is true in iTunes and iPhoto. Colloquy and Coda. Etc.)
Note also that the horizontal splitter stays in the same place — the message view shrinks and grows, but the splitter stays in the same place.
It gives a feeling of physical stability, I think. For a counter-example, try Safari’s bookmarks manager — the source list on the left does not stay at a constant width as you resize the window. And it feels a little weird.
2. Source list x origin
Consider this detail from Mail’s source list:
Now consider this from an app made by an independent developer:
Set aside that the second app isn’t using the source list background color or selection gradient — note the extra outline between the selection and the window border.
Here they are blown up, so you can see what I’m talking about:
Here’s the secret: the x origin for the source list needs to be -1, not 0, to hide that outline. (Or maybe you can set it not to be bordered, or whatever — as long as that outline doesn’t show.)
I’ve used a few different XML parsers on Mac OS X—including CoreFoundation’s XML parser and NSXMLDocument.
But recently, for technical reasons, I couldn’t use any of the XML parsers I was already using. And, furthermore, I had reason to want to use a stream-based parser rather than a parser that builds a tree. (For better performance and lower memory use.)
I figured that probably meant using a SAX-ish API. (SAX == Simple API for XML) But I’ve never wanted to deal with SAX because it meant writing a bunch of code to deal with state, and that’s just a pain. (Honestly. No matter what Gus says.)
So I found my way to libxml2 and its SAX2 module. Eh, okay, I’ll do this, I guess. Maybe it’ll even be fun! (Really thinking, probably not fun.)
Then somehow I ran across the xmlreader module. It turns out to be exactly what I wanted—stream-based and fast—without being a big pain like SAX.
(It’s a clone of the xmlReader .NET interface. It’s possible that it’s very commonly-used in the Windows world.)
xmlTextReader works like this:
loop until done GetTheNextBitOfXML DoSomethingWithItIfYouWant
Right. No callback functions (as in SAX). Just loop through the XML until you’re done.
And here’s a demo project (BSTweetParser) that downloads the Twitter public timeline and parses it into Cocoa objects, an array of dictionaries. (Twitter stuff makes for great sample code.)