@synthesized实例variables的可见性是什么?
如果您的公共界面中有一个属性,如下所示
@interface MyClass : NSObject @property(strong) NSString *myProp; @end
然后综合它,实际上综合variables:
@implementation MyClass @synthesize myProp = _myProp; // or just leave it at the default name.. @end
什么是实例variables_myProp
的可见性? 也就是说,这是考虑@public
, @protected
或@public
@protected
? 我猜,因为MySubClass
可以从MyClass
inheritance,那么它也将获得属性(自然),但它也会inheritance实例variables的可见性?
如果我把这个属性放在一个类扩展中,它有什么不同? 这会隐藏子类的属性,我也猜测实例variables。 这是logging在任何地方?
对于所有无法看到@synthesize
行(基本上意味着.m文件之外的任何内容)的代码,合成的ivar是完全不可见的 。 这不是@protected
,它不是@protected
,它只是未知。 用@private
ivar,其他代码试图访问它将被告知它是私人的,但是对于一个合成的ivar,试图访问它的其他代码将被告知该字段根本不存在。
作为一个思想实验,试着想象一下,伊娃像是被@protected
。 你做了一个子类,然后你在那里和伊娃混在一起。 现在你回到超类,把@synthesize myProp
@synthesize myProp=foo
。 在子类中会发生什么? 当编译器处理子类时,它不能看到 @synthesize
行,所以不知道你只是改变了伊娃的名字。 事实上,它甚至无法确定该财产是否由伊娃支持,或者是否使用定制的访问方法实施。 我希望这很明显,为什么这意味着这个子类不可能访问伊娃,而其他任何一个类别都不能。
也就是说,我不太清楚编译器如果在试图访问伊娃的同一个.m文件中编写代码。 我期望它会把伊娃作为@private
(因为编译器实际上可以看到伊娃存在)。
而且,这对运行时方法没有任何影响。 其他类仍然可以使用obj-c运行时方法来dynamic查找你的类的ivar列表,并用它来查找。
如果它是在你的界面中声明的,那么在使用@property
声明的时候它几乎是公开的。 如果你想使用@property
声明,并保持它们的属性真正私有,你应该在你的实现中创build一个私有类。
MyClass.h
@interface MyClass : NSObject { @private NSObject* foo; } @end
MyClass.m
#import "ClassWithPrivateProperty.h" @interface MyClass () @property (nonatomic,retain) NSObject* foo; @end @implementation MyClass @synthesize foo; // class implementation... @end
合成variables的作用就像声明@private
:
@interface Garble : NSObject @property (copy) NSString * s; @end @implementation Garble @synthesize s; @end @interface Bargle : Garble @end @implementation Bargle - (void) useS { NSLog(@"%@", s); // error: instance variable 's' is private } @end
我发誓我在文档中看到过这个,但是现在我找不到它了。 如果我追踪它,将会更新。
您可以创build一个dynamic属性,并向编译器指出它的实例化将在运行时。
然后在你的子类中写自己的getter或合成属性。
@interface BaseClass:NSObject
@属性(非primefaces,强)NSString * ThisWillBeSynthesizedInRespectiveSubclasses;
@结束
@implementation BaseClass
@dynamic ThisWillBeSynthesizedInRespectiveSubclasses;
@结束
在子类中
@interface子类:BaseClass
@结束
@implementation Subclass @synthesize ThisWillBeSynthesizedInRespectiveSubclasses = _ThisWillBeSynthesizedInRespectiveSubclasses;
@结束
或者你写自己的setter / getter方法。
希望这可以帮助 !
其他类可以访问#include
所有内容。 换句话说,就是你头里的东西。
如果某些东西只出现在你的实现文件中,其他类(包括子类)不知道它存在。 综合性质就是这样。 其他类只知道属性(一个属性意味着一个getter和一个setter方法),但他们不知道其方法的内部实现。
请注意,obj-c中的访问说明符(public / private / protected)只是编译器的一个提示,即使头文件中出现了某些内容,也不能访问。 运行时不会以任何方式检查它。
如果将它放入类扩展中,会发生什么? 请注意,属性是一组两个方法。 你只要隐藏每个类的方法,包括你的类主标题,但不包括类扩展标题。
我们用这个例子来声明一个属性是只读的,在类的继续中,我们声明它是readwrite。 然后,我们只能从课堂内部使用setter。