Thursday, April 26, 2012
No WWDC for me this year!
You snooze you loose. Plus I have gigs galore in June. Plus the session videos will probably suffice.
Monday, April 9, 2012
Kodagram
Kodak, a company with vast manufacturing capacity and patents to key photographic technology, and the ability to make pictures look great, is worthless. Instagram, a company with no way to make money and that only knows how to make your photos look like they were take with a broken film camera, is worth a billion.
Oh the irony.
Oh the irony.
Wednesday, April 4, 2012
Blocks instead of RAII
Many C++ programmers are familiar with the resource-aquisition-is-initialization pattern, where a class's constructor and destructor manage the acquiring and releasing of a resource, typically a lock such a mutex. Before blocks were added to Objective-C, I missed this pattern because I felt it made it so much easier to get things right and keep code maintainable. Blocks provide an equally clean way to factor the acquiring and releasing of a resource into reusable code that achieves the same goal, but rather than create a class, you create a function.
For example, an OS X IOSurfaceRef must be locked before accessing the data with the CPU. The calls to lock and unlock the surface are simple enough, but why repeat them? Here's a function that does that clearly:
And a call to that looks like:
This pattern ensures that you get consistent behavior wherever in your code you need to read data from an IOSurface, getting the appropriate error values, and always keeping the calls balanced, which is critical.
For example, an OS X IOSurfaceRef must be locked before accessing the data with the CPU. The calls to lock and unlock the surface are simple enough, but why repeat them? Here's a function that does that clearly:
OSStatus CallBlockWithIOSurfaceLockedForReading(IOSurfaceRef surface, OSStatus (^block)(void))
{
uint32_t seed = 0;
OSStatus error = IOSurfaceLock(surface, kIOSurfaceLockReadOnly, &seed);
if (!error)
{
error = block();
OSStatus unlockError = IOSurfaceUnlock(surface, kIOSurfaceLockReadOnly, &seed);
if (!error)
error = unlockError;
}
return error;
}
And a call to that looks like:
CallBlockWithIOSurfaceLockedForReading(surface, ^OSStatus{
void *bytes = IOSurfaceGetBaseAddress(surface);
// do something with bytes here.
// do something with bytes here.
return noErr;
});
This pattern ensures that you get consistent behavior wherever in your code you need to read data from an IOSurface, getting the appropriate error values, and always keeping the calls balanced, which is critical.
Subscribe to:
Posts (Atom)