November 2011
1 post
TCMMyClassWithSingleton.sharedInstance
PSA: I switched to dot syntax for Singletons now. Seems fitting, looks less cluttered. I took some time getting used to it, but now I really like it.
[NSUserDefaults.standardUserDefaults boolForKey:@"SomeKey"]; [NSNotificationCenter.defaultCenter postNotificationName…];
July 2011
1 post
Network Testing
If you put in network code into your apps, it is always important to test against bad network conditions. While this isn’t too trivial, it was always possible using dummynet.
However, now new in Lion is a Preference pane to use, so you don’t have any excuses anymore for not testing: Network Link Conditioner - Use it and use it heavily - real life network conditions, especially on iOS,...
May 2011
2 posts
Could the Mac become a Post-PC device?
Today I did a little mind experiment thinking about if an ARM based MacBook Air would be viable, and what would be the pros and cons.
Pros:
Battery life
Return to in house chip development
iOS and Mac running on the same architectures
Probably a good long term bet, as ARM is here to stay and winning the performance per watt battle
Cons:
No Bootcamp, parallels or the such
No Rosetta-like...
0x8badf00d, Core Data and Migration
Let’s begin with the basics. In iOS there is a watchdog process - a watchdog that checks if an App takes more than about 20 seconds to start without getting back to the OS it will be killed. In the crash reports this killing is indicated by an exception code of 0x8badf00d - Ate Bad Food. Getting back to the OS more or less means that your delegate call of...
April 2011
2 posts
Didn’t we used to make fun of Eclipse for stuff like this?
– I could not agree more. (via The Powers of Observation)
Be very careful when calling...
rentzsch:
Samuel Défago:
Never ever use -[NSNotificationCenter removeObserver:] to unregister from notification events, except from a dealloc method. This might cancel registrations made by a parent class, and you cannot know how a parent class is implemented (at least you shouldn’t care). Stick to this rule even if your parent class is NSObject: Your class hierarchy might change in the...
March 2011
1 post
UIEdgeInsets
A common task for UIKit devs: Inset a CGRect by an amount from each edge:
UIEdgeInsetsInsetRect(rect,insets);
And to do that in one line of course the constructor of UIEdgeInsets
UIEdgeInsetsMake(top,left,bottom,right);
Why on earth they decided to make the order of insets the other way round as CSS will remain a mysterie. Also note that a negative inset expands towards this edge. E.g.
...
August 2010
1 post
Great Summary of the Fast App Switching iOS4... →
July 2010
1 post
The hidden complexity of iOS 4 Multitasking
Just a Quick list of what to keep in mind when designing your app with the new Fast App Switching in place:
the entry point of your app might be anywhere and data may have changed. Even built in Apps like the Photos app get that one wrong. Have the Photos app open. Make new pictures. Go back. Or worse: download and delete all the fotos to iPhoto. Reopen the Photos app: crash.
if something goes...
May 2010
1 post
Separation of Tasks
If you know me, you might know that I don’t like Xcode’s internal Documentation Viewer and don’t use the internal editor. My reasons: I need my Tasks separated. Source files are in SubEthaEdit, Project files, compilation, console feedback, debugger are in Xcode, Source control management is in the terminal, and Documentation is in AppKiDo (and AppKiDo-for-iPhone). Why? Quick and...
April 2010
2 posts
great setup and extension tips for mercurial →
NSString stringWithFormat: - indexed arguments!
A IMHO quite underused feature of the format string is indexed parameter referencing. Something that can’t be found easily in the documentation sadly, but is quite crucial for good localization and can be also be used if you want to use an argument more than once:
NSString *formatString = @"Page %1$d of %2$d"; [NSString stringWithFormat:formatString,5,120]; // results in @"Page 5 of 120"
...
March 2010
6 posts
Choosing the right spot for your task
Usually life with Cocoa is nice. You have hooks and handles for every occasion. However - sometimes you are not looking in the right place, or have no idea this hook you need exists at all.
A strange and interesting example from SubEthaEdit is the [NSAttributedString doubleClickAtIndex:] method. I had to ask for that at WWDC because I was sure this kind of functionality would either be named...
Handy constants
Another element that is easily overlooked, but can make code and life so much easier: Convenience Constants. Take some examples:
CGPointZero
CGRectZero
CGSizeZero
CGRectInfinite - mostly used in Core Image contexts
CGRectNull - not equal to CGRectZero, returned by e.g. CGRectIntersection()
NSNotFound
CGAffineTransformIdentity
UIEdgeInsetsZero
UITrackingRunLoopMode
...
Cocoa is object oriented, right?
Of course it is. And greatly designed too if you ask me. However there is a huge world of regular functions and macros which you might have overlooked. Here are some of my favorites:
UIImagePNGRepresentation(image)
UIImageJPEGRepresentation(image,quality)
UIImageWriteToSavedPhotosAlbum(image,target,selector,context)
UIInterfaceOrientationIsLandscape(orientation)
...
Occam's Razor
In debugging a Problem always, I repeat, always apply Occam’s Razor and look for the simplest solution out there. 9 out of 10 times it is the blatant obvious errors you are just attributing to some higher power, deeper edge case or otherwise dark wizardry.
Our brains are wired this way, we see connections where there are none, we associate. I’ve seen it time over time, and experienced...
+initialize
When implementing a Cocoa Classes +initialize method, don’t forget to check if you are you, otherwise you might get called twice!
@implementation MyCustomClass +(void)initialize { if (self == [MyCustomClass class]) { // do your stuff here! } }
Retain, Release, Autorelease, etc.
Something I tend to do, which saved my but quite some time. Interestingly enough this is somewhat discouraged in iPhone OS due to the overhead of autoreleases and the relatively small power of the platform.
Instead of:
SomeClass *myInstance = [[SomeClass alloc] init]; // do something with myInstance [myInstance release]; // release it again
I do:
SomeClass *myInstance = [[[SomeClass alloc]...