分配只读属性

时间:2013-07-18 11:06:40

标签: ios objective-c

我有以下代码:

-(id) initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t
{
    self = [super init];

    if (self)
    {
        coordinate = c;
        self.title = t;
    }

    return self;
}

其中coordinate是:

@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;

我有两个问题:

  • 可以分配给只读的属性吗?
  • 不应该coordinate之前有self吗? (例如,self.coordinate = c)。

PS。我使用这段代码没有任何错误 - 这是一本书的例子。

8 个答案:

答案 0 :(得分:15)

你应该写:self.coordinate = c等于[self setCoordinate:c] - 调用setter方法。但是你不能这样做,因为你会得到Assignment to readonly property错误。只读属性没有setter方法。在你的情况下,你只需设置直接支持属性的ivar,它是记录良好的行为。 ivar名称将是前缀为下划线的属性名称,因为在您的情况下,如您所说,您有一个明确的@synthesize,因此ivar将具有相同的名称,这就是为什么您没有任何名称编译问题。该属性可以是只读的,但可以由类写入 - 这涉及在类扩展中声明setter方法或在扩展中重新声明属性。为此,您可以参考以下帖子:Objective-C property that is readonly publicly, but has a private setter

答案 1 :(得分:3)

  • 可以分配给只读的属性吗?

    是的,如果您不希望在其包含的实例之外更改属性,则可以。

    例如:数组的count属性,这里count是一个依赖于数组保留的对象数的属性。所以不应该从Array对象外面修改它。

  • 之前不应该协调自己吗? (例如,self.coordinate = c)。

    如果只读,则无法通过setter方法修改属性。

    self.coordinate转换为[self setCoordinate:],这是不允许的,只允许setter方法修改属性。

所以你应该直接设置ivar,这只能从定义了readonly属性的对象内部完成。

_coordinate = value; //or coordinate = value if you have synthesized it. 

如果你很好奇,

self.propertyName && self.property = indirectly calls getter and setter method.

在实施过程中,setter和getter帮助_ivars公开 - 可以访问公共财产。

- (void)setProperty(value) //self.property = value
 {
    _property = value;
 }

- (id)property  //self.property
  {
     return _property;
  }

答案 2 :(得分:1)

您无法使用readonly属性为变量赋值,但是从iOS6开始,可以自动添加@synthesize,因此您可以使用ivar替换它。喜欢 _test = @“test”替换self.test = @“test”如果test的属性是readonly。

答案 3 :(得分:0)

  1. 不,那不行。分配readonly的正确方法是这样的:

    - (CLLocationCoordinate2D)coordinate {
    
        //create the struct and return it.
    
        return value;
    
    }
    
  2. 不,不是相反。您应该像这样设置title

    _title = t;
    

答案 4 :(得分:0)

coordinate = c;未分配属性,它正在分配具有相同名称的实例变量。无法分配只读属性,这就是“只读”的含义。如果将其更改为self.coordinate = c,则会出现错误,除非在类扩展中将此属性重新声明为readwrite。

答案 5 :(得分:0)

  

可以分配给只读的属性吗?

如果你使用像你一样的合成访问器,那就完全没问题了。

  

之前不应该协调自己吗? (例如,self.coordinate = c)。

self.coordinate是非合成访问器的快捷方式。这个setter在类外部是可见的,因此对于类用户来说,该属性应该是只读的,如果尝试使用点表示法访问readonly属性,则会出现编译器错误。你的代码是正确的。

答案 6 :(得分:0)

  

可以分配给只读的属性吗?

如果您@synthesize coordinate;,则支持ivar将命名为coordinate。如果属性是自动合成的,则会将其命名为_coordinate

如果您的意图是在初始化程序中分配基础实例变量,那就没问题(例如coordinate = c_coordinate = c)。

如果你想使用setter设置它(例如[self setCoordinate:c]self.coordinate = c;,你需要自己实现setter或合成它的定义(例如通过在类继续中声明属性readwrite)。


  

之前不应该协调自己吗? (例如,self.coordinate = c)。

不,it should not。在部分构造的状态下使用直接访问,例如初始化程序或-dealloc

鉴于属性:

@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy, readwrite) NSString * title;

您的初始化程序应采用以下形式:

- (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

答案 7 :(得分:0)

我见过狡猾的人这样做....

Source.h

@property (readonly) BOOL  isRunning;

Source.m

- (void) blahBlahBlah { ...
   self->_isRunning = YES; ...

我可以找到关于这些类型的访问器的文档很少...我很确定它只是一个标准的C构造...我不是很熟悉...但这是一种方式如果你掌握了这个主题......比我的好......