Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I declare a @property but prevent its ivar from being created?

I have class A, which exposes a way of getting and setting an object of type Foo. In property parlance, I generally declare this in the interface:

@property (nonatomic, strong) Foo * foo;

This (in modern ObjC) generates both the accessors and an ivar, _foo for storage.

If I want to do custom work in the accessors, I can implement one or both of them myself. But what if I not only want to do custom work, I actually don't want the ivar? In other words, I'm doing something else with the Foo object, like handing it back and forth to another internal object that I'm composed with. I don't actually need to keep storage for foo in the instance of A at all.

It seems like I have two choices:

  1. Declare the property, implement both accessors, and simply ignore the fact that the compiler creates storage for _foo, and never use it.
  2. Declare my accessors explicitly: - (Foo *)foo and - (void)setFoo:(Foo *)foo in the interface, like I used to in pre-modern ObjC.

The first seems inelegant at runtime, and the second seems inelegant in the declaration (where I'd probably now have a mix of properties and property-like accessors).

Is there a way to declare a property and have it serve as purely a declaration?

like image 923
Ben Zotto Avatar asked Oct 27 '13 23:10

Ben Zotto


1 Answers

Use the @dynamic keyword in the implementation file. The usual discussion of @dynamic describes it as not creating the accessors at compile time. Not usually mentioned is that is also has the effect of doing nothing to create storage for the property, which is exactly what is desirable in this case.

@implementation A
@dynamic foo;

- (Foo *)foo 
{
   // get a Foo from somewhere and return it.
}

- (void)setFoo:(Foo *)foo
{
   // do something with foo
}

@end

(Note: answered my own question since I discovered this while writing up the question and it seemed interesting and nonobvious.)

like image 64
Ben Zotto Avatar answered Sep 18 '22 14:09

Ben Zotto