From a StackOverflow posting.
When I teach Cocoa, I always ask the class what their background is in. This generally tells me what they need to unlearn before they’re ready for Cocoa. Here are some of the things I’ve found that different groups need to unlearn. Read more…
Now that we’re past the New Year, and I have a chance to reorganize my schedule, I’m working up my next series of postings. While you’re all patiently waiting, go read gotoAndPlay. I started out helping Geri on some layer drawing questions on StackOverflow, and have really gotten interested in his efforts to make his apps really beautiful.
PandoraBoy’s user interface is pretty screwed up since the recent Pandora update. I’ve talked with Pandora and it’s a known problem with WebKit. You’ll see the same issues if you run Safari. Pandora is working on a fix, and when they deploy it, PandoraBoy should automatically work again.
NSCopying is not always as simple to implement as you would think. Apple has a good write-up discussing the complexities, but let me elaborate. Forgive some ranting digressions. It’s important to know how to work around the problems I’m going to discuss, but it’s also important to understand how insane it is to have to work around this issue.
First, there’s the fairly obvious problem of deep versus shallow copies. If object foo has an instance variable *bar, should a copy of foo have a second pointer to bar, or should it have its own copy of whatever bar points to? There is no way to answer this question generally; it depends on the nature of the objects.
Most of the time, this can be dealt with fairly easily by implementing the accessors with the correct behavior (retain versus copy), and you wind up with a copyWithZone: like this:
- (id)copyWithZone:(NSZone *)zone
{
Product *copy = [[[self class] allocWithZone: zone]];
[copy setProductName:[self productName]];
return copy;
}
That works really well as long as your superclass doesn’t implement NSCopying, but if it does, you may not have enough information or access to cleanly copy it. Now you would think this would be easy:
- (id)copyWithZone:(NSZone *)zone
{
Product *copy = [super copy];
[copy setProductName:[self productName]];
return copy;
}
But that may or may not work. If super implements -copyWithZone: as described above, then all is fine. But what if your superclass uses NSCopyObject()? Things go badly, and in ways very difficult to understand and debug. Read more…
I work on a lot of projects that share significant code between iPhone and Mac versions. This is the beauty of Cocoa. While working on these projects, I’ve bumped into this idiom many times:
#ifdef TARGET_OS_IPHONE
#import <uikit /UIKit.h>
#else
#import <cocoa /Cocoa.h>
#endif
This is almost never correct, and almost always means that someone imported Cocoa.h into a model class. Model classes should never rely on UIKit or Cocoa. They should just import Foundation.h.
There is one interesting exception that we’ve run into: NSImage versus UIImage. These are really model classes, but they’re part of AppKit and UIKit. They have very similar interfaces, so in most code you should be able to interchange them and keep everything portable. What to do?
Read more…
I keep coming across code like this:
newMonster.trueName = [NSString stringWithString:@"New Monster"];
It’s time to say stop it already with the extra +stringWithString:. I haven’t worked out yet where this anti-pattern comes from. Maybe it’s a misunderstanding of some sample code in Kochan? Maybe it’s a Java/.NET thing? I’m not sure. But I see it so often from so many places that it’s clearly something that needs discussing. (The rest of the linked article is good; it just gave me a good example of this issue.)
Read more…
Observing NSNotifications in a view control is a good thing. But remember, just because you’re not onscreen doesn’t mean that you’re not still observing. This is particularly noteworthy on iPhone, where your view can get dropped any time memory is tight and you’re offscreen, but it can bite you anywhere.
ViewControllers, WindowControllers and other UI controllers are often better off registering and uregistering for notifications when they are put on and off the screen rather than when they are allocated and deallocated. This often means that they will need to update their state when put on screen. For example, an icon indicating “connected” might be part of a StatusViewController. When StatusView comes on screen, StatusViewController should update the connected status and then begin observing changes on it. When StatusView goes off screen, StatusViewController should stop observing.
Read more…
Based on a post at StackOverflow. The question was whether Objective-C is only used for development on Mac OS/iPhone and why.
I think ObjC has been isolated to the Apple world through a quirk of history and the nature of proprietary systems.
Read more…
It thought I was going to be quiet for two weeks, now three posts in a day. There was a good question on Stack Overflow about getting system information. The actual question is “what does system_profiler actually do?” But it’s a good way to show how to begin to understand how any program works on the Mac. Here are some of the most basic tools of the trade. This is not a deep tutorial on reverse engineering. It’s a whirlwind tour of how you begin to attack programs using pretty standard tools. I’m not getting into any of the anti-obfuscation tools like Onyx the Black Cat or commercial tools like IDA Pro, or even code injection like SIMBL or F-ScriptAnywhere. When you think you’re going to hide how your program works, make sure you research those first. You’ll learn quickly how hard that really is. Maybe you should read my thoughts about Obfuscating Cocoa.
Read more…
We recently had a discussion on cocoa-students (the excellent list for Big Nerd Ranch alumni; yet another reason to go to BNR classes) about protecting Cocoa programs from reverse engineering, mostly around some anti-copying code. I had some thoughts on the subject since I happen to have a background in anti-counterfeiting.
Cocoa is a reverse-engineer’s dream. Spend some time at culater before dreaming you can really protect a Cocoa program. Objective-C is meant to be highly readable both in source and at run time. Obfuscation is not in its nature. This only points out Objective-C’s particular difficulties in this area; it is not to suggest C or C++ will save you. They’re just not quite as trivial as Objective-C.
That said, the world of obfuscation falls into three big camps: you can try to deal with 70% of your problem, 75% of your problem or 90% of your problem.
Read more…