Wednesday, July 07th, 01:59 PM
Fun with CocoaCheck out this amazing stop motion Lego Spider-Man movie.
I've been working to get the FeedTicker code completed by the time I leave to visit my parents and sister later this month. So far I seem to be extremely good at hitting my head against a brick wall. I've finally breached it I believe, at least on some levels. Here's some highlights:
- I came across a bug in
NSURLConnection's handling of its cache. Apparently if you tell it to not use a cached copy it does the query but still caches the new data it downloads. This makes sense; if another connection comes along and wants the same URL but doesn't mind a cached copy it would be inefficient to download it twice. The problem is that a cached copy is kept for every download even if the URL is the same. When I upped the download rate to 5 seconds/download for testing purposes my application leaked memory like a sieve. I think this is an actual bug in the Foundation class, I've seen it alluded to elsewhere but I can't seem to find it at the moment (alas, Google has failed me). The workaround was something I should have done in the first place; useNSURLConnection'sconnection:willCacheResponse:delegate method to disable the cache completely. Unfortunately this required me to use the connection asynchronously instead of the much hailedsendSynchronousRequest:returningResponse:error:class method. This seemed an improvement at first until I came across the next issue which coupled with my misunderstanding with the way the connection delegate methods andNSTimerdelegate methods work started the wall-bashing process: - The Joy of Multithreading. Objective-C has a very simple and elegant way of multithreading an application. Coming from the Java camp where I had coded quite a number of multithreaded applications over the years I was surprised that it was even easier to implement; it comes close to trivial. I'm close to saying it shouldn't be this easy because the potential pitfalls can be hair-tearingly vicious. I'm an experienced Java coder, I didn't think twice about firing off another thread to offload some upkeep from the main thread so the animation wouldn't be affected. I used
NSLockto lock down potential race conditions, all of the usual stuff. Imagine my surprise when I was gettingEXC_BAD_ACCESSexceptions in the middle of one ofNSURLConnection's delegate methods. Firing up the debugger I found that at the point of exception, the entire object the method was called on had gone out of scope. I mean everything,selfwas "out of scope". It's one of those "guh?" moments. It seems that when the first thread is split off Cocoa enters a "multithreaded mode" which "activates greater thread safety measures". My guess was that somehow the creation of my objects had been done in a separate thread from the main thread that was either not allowing access in some way or, more likely, that the thread that had created them had exited, wiping out its autorelease pool and my data objects in the process. Moving the creation of the objects to theinitmethod (where they should have been in the first place) fixed this problem, at least for now, as I'm still not sure about the goings-on. Adding to the hair-pulling part was the fact that I thoughtNSURLConnection' s andNSTimer's delegate methods were called on new threads (Java'sjava.util.Timerdoes it this way). A humbling experience overall. If all else fails, RTFM. - Now the big question that's plaguing me is why does my application, when run with the same settings, have massively inconsistent rates of processor usage according to
top? I'm talking about the life of the application here, folks. Sometimes it says it's taking up <2% on average and other times it's more around the 25% range. The only way I can seem to keep this consistent is when I run it in the debugger. It's also, on average, always below 2%. Baffling. Annoying. Difficult to debug.
FeedTicker
Gee!