简体   繁体   English

Objective-C / Cocoa:如何为readonly属性设置值?

[英]Objective-C/Cocoa: How to set value for a readonly property?

I found that some objects are defined so that a readonly property is set by an external object, somehow. 我发现定义了一些对象,以便以某种方式由外部对象设置readonly属性。 For example, in: 例如,在:

// skview is an instance of SKView
// skscene is an instance of SKScene
[skview presentScene:skscene]

skscene's 'view' property, which is readonly, is set to skview. skscene的'view'属性是readonly,设置为skview。

How is this possible if property skview.view is readonly? 如果属性skview.view是readonly,这怎么可能? How can this behaviour be implemented in custom objects? 如何在自定义对象中实现此行为?

Thanks! 谢谢!

If you declare a property in you .h file and set it as readonly , you can redeclare it in the .m file (in the continuation category) as readwrite , so you can directly edit the value. 如果在.h文件中声明属性并将其设置为readonly ,则可以在.m文件(在延续类别中)将其重新声明为readwrite ,这样您就可以直接编辑该值。

But that's just the clean way of doing things. 但这只是干净的做事方式。 You can also use KVC to be a bit more back-door about it and just call setValue:forKey: which bypasses any of the nice stuff you might have done to specify what you want to be public. 你也可以使用KVC更多关于它的后门,只需调用setValue:forKey:它绕过了你可能已经完成的任何好的东西来指定你想要公开的东西。

Check this for a description of what KVC will do to fulfil your request. 请查看此信息 ,了解KVC将如何处理您的请求。

Then, if you get really desperate, you can use the Obj-C runtime to get direct access to the underlying instance variables. 然后,如果您真的绝望,可以使用Obj-C运行时直接访问底层实例变量。

The key to understanding this is to recognise the fundamental distinction between "interface" and "implementation". 理解这一点的关键是要认识到“界面”和“实施”之间的根本区别。

The @interface defines the PUBLICLY VISIBLE face that your particular object wants to present. @interface定义了您的特定对象想要呈现的PUBLICLY VISIBLE面。 To the outside world, it can declare that "this value is read-only, you may not change it". 对于外界,它可以声明“此值是只读的,您可能不会更改它”。

Internally, however, the implementation is free to make it read-write, to directly access the backing store that the interface is exposing, or to implement the read-only property as a computation, something that does not represent a simple variable. 但是,在内部,实现可以自由地使其成为读写,直接访问接口正在公开的后备存储,或者将只读属性实现为计算,这不代表一个简单的变量。

For example, imagine a property called 'firstSubview' - this readonly property would be implemented by retrieving the list of all subviews, then returning the first in the array (or nil if there were none). 例如,想象一个名为'firstSubview'的属性 - 这个只读属性将通过检索所有子视图的列表来实现,然后返回数组中的第一个(如果没有则返回nil)。 Making this property writeable would make little sense. 使这个属性可写是没有意义的。

Remember, an @implementation can redefine properties to be readwrite, can create its own private properties (and backing variables), etc. 请记住,@ implementation可以重新定义要读写的属性,可以创建自己的私有属性(和支持变量)等。

Think of the contents of the .h file as primarily being for everyone EXCEPT the actual implementing .m 将.h文件的内容视为主要适用于所有人,除了实际的实现.m

If you would like external projects to set this property, then you need to declare a setter. 如果您希望外部项目设置此属性,则需要声明一个setter。 So for instance you'd have in your .h file: 例如,你的.h文件中有:

@property (readonly) NSString *mySpecialString;

-(void)setMySpecialString:(NSString*)string;

Then you need to write the implementation in your .m file and you can put whatever other operations you wanted to happen at the time of assignment in there as well. 然后,您需要在.m文件中编写实现,并且您可以在分配时放置您想要执行的任何其他操作。 However, in this case there is no point in making this property readonly, as you can both read and write it. 但是,在这种情况下,将此属性设置为只读是没有意义的,因为您可以读取和写入它。

One way to use readonly properties is to make them readable to external classes, then to modify the corresponding ivars in the .m file, so that they are written to privately. 使用只读属性的一种方法是使它们对外部类可读,然后修改.m文件中相应的ivars,以便私有地写入它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM