如何声明@property但阻止其ivar被创建?

Ben*_*tto 7 cocoa objective-c

我有一个类A,它暴露了一种获取和设置类型对象的方法Foo.用属性的说法,我通常在界面中声明:

@property (nonatomic, strong) Foo * foo;
Run Code Online (Sandbox Code Playgroud)

这(在现代的ObjC中)生成存取器和ivar,_foo用于存储.

如果我想在访问器中进行自定义工作,我可以自己实现其中一个或两个.但如果我不仅想做定制工作,我实际上不想要ivar呢?换句话说,我正在使用Foo对象做其他事情,比如将它来回传递给我组成的另一个内部对象.我实际上并不需要保持储存foo在实例A都没有.

看来我有两个选择:

  1. 声明属性,实现两个访问器,并简单地忽略编译器为其创建存储的事实_foo,并且从不使用它.
  2. 明确地声明我的访问者:- (Foo *)foo并且- (void)setFoo:(Foo *)foo在界面中,就像我以前在现代的ObjC中一样.

第一个似乎在运行时不够优雅,第二个似乎在声明中不太优雅(我可能现在混合使用属性和类似属性的访问器).

有没有办法申报一个财产,并将其作为纯粹的声明?

Ben*_*tto 9

@dynamic在实现文件中使用关键字.通常的讨论@dynamic将其描述为在编译时不创建访问器.通常没有提到的是,它还具有无效为该属性创建存储的效果,这正是在这种情况下所希望的.

@implementation A
@dynamic foo;

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

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

@end
Run Code Online (Sandbox Code Playgroud)

(注意:回答我自己的问题,因为我在写这个问题时发现了这个问题,这看起来很有趣而且非显而易见.)


nhg*_*rif 5

如果您同时覆盖了setter和getter,并且没有在setter和getter中使用该变量,则不会创建变量。

举例来说,如果你有一个类,你想firstNamelastName财产,但也许也有settergetter一个fullName属性,如果你的fullName二传手只解析字符串转换成firstNamelastName,并设置这些属性是(从不完整的字符串存储到一个fullName变量),而您的fullNamegetter只是returns连接的firstName+ lastName且从不使用fullName变量,因此永远不会创建一个变量。

这是根据Apple的官方文档。 向下滚动到“您可以实现自定义访问器方法”