ios 分配只读属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17721724/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Assigning readonly property
提问by Oleksandr Karaberov
I have following code:
我有以下代码:
-(id) initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t
{
self = [super init];
if (self)
{
coordinate = c;
self.title = t;
}
return self;
}
where coordinate
is:
在哪里coordinate
:
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
I had two questions:
我有两个问题:
- is it OK to assign to a property that is readonly?
- should not
coordinate
haveself
before it? (e.g.,self.coordinate = c
).
- 可以分配给只读属性吗?
- 不应该
coordinate
有self
前呢?(例如,self.coordinate = c
)。
ps. I don't get any errors using this code - and it is an example from a book.
附:使用此代码我没有遇到任何错误 - 这是书中的一个例子。
回答by Oleksandr Karaberov
You should write: self.coordinate = c
which is equal to [self setCoordinate:c]
- calling setter method. But you can't do this because you will get Assignment to readonly property
error. Read-only properties don't have setter methods.In your case you just set the ivar which backs the property directly and it is well documented behavior. The ivar
name will be the property name prefixed with an underscore BUT as in your case you have an explicit @synthesize
as you said, so the ivar will have the same name and that's why you haven't any compiler issues. It is possible for the property to be read-only publicly, but be writeable by the class - this involves either declaring a setter method in a class extension or redeclaring the property in the extension. For this you can refer this post: Objective-C property that is readonly publicly, but has a private setter
你应该写:self.coordinate = c
这等于[self setCoordinate:c]
- 调用 setter 方法。但是你不能这样做,因为你会得到Assignment to readonly property
错误。只读属性没有 setter 方法。在您的情况下,您只需设置直接支持该属性的 ivar,这是有据可查的行为。该ivar
名称将是带有下划线前缀的属性名称,但在您的情况下,您有一个明确@synthesize
的名称,因此 ivar 将具有相同的名称,这就是为什么您没有任何编译器问题的原因。属性可能是公开只读的,但可由类写入 - 这涉及在类扩展中声明 setter 方法或在扩展中重新声明属性。为此,您可以参考这篇文章:公开只读但具有私有 setter 的 Objective-C 属性
回答by Jesly Varghese
is it OK to assign to a property that is readonly?
Yes, its okay if you don't want a property to be mutated outside its containing instance.
eg: count property of an array, here count is a property that is dependent on the number of objects retained by the array. So it shouldn't be modified from outside the Array object.
should not coordinate have self before it? (e.g., self.coordinate = c).
If read only, you can't modify your property via a setter method.
self.coordinate translates to [self setCoordinate:] which is not permitted as read only prevents setter methods from modifying the property.
可以分配给只读属性吗?
是的,如果您不希望属性在其包含的实例之外发生变异,那也没关系。
eg:数组的count属性,这里count是一个依赖于数组保留的对象数量的属性。因此不应从 Array 对象外部修改它。
不应该协调之前有自我吗?(例如,self.coordinate = c)。
如果只读,则无法通过 setter 方法修改属性。
self.coordinate 转换为 [self setCoordinate:],这是不允许的,因为只读会阻止 setter 方法修改属性。
So you should directly set the ivar
, and this can be done only from inside the object for which readonly property is defined.
所以你应该直接设置ivar
,这只能从定义了 readonly 属性的对象内部完成。
i.e
IE
_coordinate = value; //or coordinate = value if you have synthesized it.
If you are curious,
如果你好奇,
self.propertyName && self.property = indirectly calls getter and setter method.
And in implementation, setters and getter help the _ivars to be public-ally accessible is the property is public.
在实现中,setter 和 getter 帮助 _ivars 可以公开访问,因为属性是公开的。
- (void)setProperty(value) //self.property = value
{
_property = value;
}
- (id)property //self.property
{
return _property;
}
回答by harryyan
you cannot assign value to variable with readonly property, but from iOS6, the @synthesize can be added automatically, so you can use ivar to replace it. Like _test = @"test" to replace self.test = @"test" if the property of test is readonly.
您不能使用 readonly 属性为变量赋值,但从 iOS6 开始,@synthesize 可以自动添加,因此您可以使用 ivar 替换它。像 _test = @"test" 替换 self.test = @"test" 如果 test 的属性是只读的。
回答by Desdenova
No that is not ok. Proper way to assign
readonly
is like this:- (CLLocationCoordinate2D)coordinate { //create the struct and return it. return value; }
No it is the other way around. You should set
title
like this:_title = t;
不,那不行。正确的赋值方式
readonly
是这样的:- (CLLocationCoordinate2D)coordinate { //create the struct and return it. return value; }
不,相反。你应该这样设置
title
:_title = t;
回答by hamstergene
The line coordinate = c;
is not assigning the property, it's assigning the instance variable which has the same name. It is not possible to assign a readonly property, that's what “read only” means. If you change it to self.coordinate = c
you will get an error, unless this property is redeclared as readwrite in class extension.
该行coordinate = c;
不是分配属性,而是分配具有相同名称的实例变量。不可能分配只读属性,这就是“只读”的意思。如果将其更改为self.coordinate = c
您将收到错误,除非在类扩展中将此属性重新声明为 readwrite。
回答by Ramy Al Zuhouri
is it OK to assign to a property that is readonly?
可以分配给只读属性吗?
If you use synthesized accessors like you're doing, it's perfectly fine.
如果您像现在一样使用合成访问器,那完全没问题。
should not coordinate have self before it? (e.g., self.coordinate = c).
不应该协调之前有自我吗?(例如,self.coordinate = c)。
self.coordinate is a shortcut for the non synthesized accessor. This setter is visible from outside the class, so since the property should be readonly for class users, you get a compiler error if you try to access readonly properties with the dot notation. Your code is correct.
self.coordinate 是非合成访问器的快捷方式。这个 setter 是从类外部可见的,因此由于该属性对于类用户应该是只读的,如果您尝试使用点表示法访问只读属性,则会出现编译器错误。你的代码是正确的。
回答by justin
is it OK to assign to a property that is readonly?
可以分配给只读属性吗?
If you @synthesize coordinate;
, then the backing ivar will be named coordinate
. If the property is auto-synthesized, it will be named _coordinate
.
如果是@synthesize coordinate;
,则支持的 ivar 将被命名coordinate
。如果属性是自动合成的,它将被命名为_coordinate
。
If your intent is to assign to the underlying instance variable within the initializer, that is fine (e.g. coordinate = c
or _coordinate = c
).
如果您的意图是分配给初始化程序中的底层实例变量,那很好(例如coordinate = c
或_coordinate = c
)。
If you want to set it using the setter (e.g. [self setCoordinate:c]
or self.coordinate = c;
you would need to implement the setter yourself or synthesize its definition (e.g. by declaring the property readwrite in your class continuation).
如果您想使用 setter 设置它(例如,[self setCoordinate:c]
或者self.coordinate = c;
您需要自己实现 setter 或综合其定义(例如,通过在类延续中声明属性 readwrite)。
should not coordinate have self before it? (e.g., self.coordinate = c).
不应该协调之前有自我吗?(例如,self.coordinate = c)。
No, it should not. Use direct access in a partially constructed state, such as an initializer or -dealloc
.
不,不应该。在部分构造的状态下使用直接访问,例如初始化程序或-dealloc
.
Given the properties:
鉴于属性:
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy, readwrite) NSString * title;
Your initializer should take the form:
您的初始化程序应采用以下形式:
- (id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t
{
self = [super init];
if (self)
{
_coordinate = c;
_title = t.copy; // note: copy/ownership semantics match property declaration
}
return self;
}
@end
回答by Alex Gray
I've seen tricky people do this....
我见过狡猾的人这样做......
Source.h
Source.h
@property (readonly) BOOL isRunning;
Source.m
Source.m
- (void) blahBlahBlah { ...
self->_isRunning = YES; ...
There is very little documentation that I can find about these types of accessors... I'm pretty sure it is just a standard C construct... one which I am not very familiar... But this is a way to go if your mastery of the subject.. is better than mine...
关于这些类型的访问器,我能找到的文档很少……我很确定它只是一个标准的 C 构造……一个我不太熟悉的……但这是一种方法,如果你对这门学科的掌握……比我的好……