Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I override how @synthesize works in Objective C?

I'm creating a base class that has an isDirty flag. It is set any time one of its properties changes, but since it's a base class, it doesn't know what its properties are. So basically, on every subclass, I have to override every - set: method to something like this:

- (id) setName:(NSString *)value {
  if ([name isEqualToString:value]) {
    return;
  }
  [name autorelease];
  name = [value retain];
  isDirty = YES;  //Here's the important bit
}

Almost every line of that is what the automatically-synthesized setter would do. Is there any way I can override what @synthesize actually creates?

There are other options I have come up with, but they all seem like they would be much slower at runtime than this method. I've thought of things like adding an object to observe its own property changes, or creating a generic function to do all that and just pass in the address to the iVar and the new value, but that still requires overriding the setter.

Any ideas? If it makes a difference, it's for an iPhone app.

like image 770
Ed Marty Avatar asked Sep 16 '09 14:09

Ed Marty


1 Answers

Several issues here:

(1) If you are concerned about setter performance, you shouldn't be using -isEqualToString: in your setter. Do a pointer compare instead because that is all that matters in this context.

(2) If you have an NSString attribute, you should be copying on set. Copy is free for immutable strings and will save your bacon for mutable strings (by preventing the caller from mutating the string out from under you).

(3) Again with performance; you checked for equality, but then use autorelease. That incurs unnecessary overhead.

(4) * they all seem like they would be much slower at runtime* indicates that you haven't actually tried it, haven't identified a performance problem, and are prematurely optimizing your code. Given (1) and (3), there is likely much more easily addressed performance issues.

My suggestions:

(1) Use @synthesize. It will generate correct and fast code, addressing (1) and (3).

(2) Use KVO or one of the other mechanisms. Until you identify a performance problem through instrumentation and quantification, you don't have a performance problem.

(3) Consider using CoreData (unless, of course, you are targeting OS 2.x). The example code is from something that is obviously a model object. If your code is nicely factored into model/view/controller, using CoreData at the model layer can both simplify your application and CoreData does a wonderful job of change tracking.

like image 56
bbum Avatar answered Oct 06 '22 12:10

bbum