OS 2.2.1和OS 3之间的Objective-C变化?

Ron*_*bro 7 iphone objective-c iphone-sdk-3.0

当我尝试为OS 3编译我的应用程序时遇到以下错误:

错误:访问者的类型与属性的类型不匹配

错误是我尝试访问的属性,定义如下:

NSMutableArray *myArray

@property (readonly,nonatomic) NSArray* myArray;
Run Code Online (Sandbox Code Playgroud)

该属性在实现文件中是@synthesized.

这在OS 2.2.1中运行得很好,但不是OS 3.0

自己编写getter方法解决了这个问题.

有人知道OS 2.2.1和3.0之间的objective-c的变化吗?这些变化有没有文件?

API文档的变化似乎并没有包含有关此问题的任何东西.

编辑

当您尝试访问该属性时发生错误,例如

NSArray *anArray = myClass.myArray;
Run Code Online (Sandbox Code Playgroud)

正如我在上面提到的,我找到了一个解决方法:自己编写getter方法,但是我真正想要的是来自apple的一些文档,解释了这个更改以及与API无关的任何其他更改.

谢谢你的帮助

Chr*_*son 17

这是编译器错误.

虽然您没有完全指定它,但我希望您的代码如下所示:

@interface Foo : NSObject {
    NSMutableArray *objects;
}
@property (readonly, copy) NSArray *objects;
@end

@implementation Foo
@synthesize objects;
@end
Run Code Online (Sandbox Code Playgroud)

遗憾的是,编译器在objects 属性声明和objects 实例变量声明之间混淆.请记住,Objective-C中的属性和实例变量是不同的东西; 属性可以由实例变量支持,但它实际上是类的公共接口的一部分.

您可以通过更改代码来清楚地将实例变量的定义与属性的定义分开,例如通过为实例变量的名称添加前缀来解决此问题:

@interface Foo : NSObject {
    NSMutableArray *_objects;
}
@property (readonly, copy) NSArray *objects;
@end

@implementation Foo
@synthesize objects = _objects;
@end
Run Code Online (Sandbox Code Playgroud)

这样编译器就不会混淆属性与表达式中的实例变量的混淆self.objects(不管怎样它都不应该,但显然是这样).

只是为了阻止不可避免的响应:Apple 没有为实例变量保留下划线前缀.它保留用于方法.无论如何,如果您不喜欢下划线,请随意使用其他前缀.

  • Ron,你刚才有一个简单的变量声明,而不是@interface中的ivar声明.此外,(只读,复制)将起作用并且非常明智:它表示该属性使用"复制"样式的内存管理,并且在此类中是只读的.(子类可以覆盖它.)最后,我重申它在iPhone OS 3.0 SDK之前工作,并且由于编译器错误而无法在iPhone OS 3.0 SDK中工作.您可以自己阅读"Objective-C 2.0编程语言",看看该语言的行为应该是什么. (6认同)
  • 这是一个错误(<rdar:// problem/6083666>)并且没有任何关于你的描述表明它只是那个错误.没有"听从你的话",克里斯的描述是准确的. (2认同)

e.J*_*mes 5

编辑:在同行评审发现缺少原始答案后删除.请阅读Chris Hanson对此事的评论.我将其余的留在这里因为我认为它仍然有效.


请注意,即使你声明属性类型是NSArray,返回的对象仍然是一个NSMutableArray,和可变的方法为它定义.以这种方式声明属性不会阻止某人意外地改变阵列.

如果要确保返回的数组不可变,可以像在原始示例中一样声明属性,然后滚动自己的访问器:

- (NSArray *)myArray { return [NSArray arrayWithArray:myArray]; }
Run Code Online (Sandbox Code Playgroud)

请注意,这将返回未保留的NSArray.如果需要持久化,则由调用者来取得对象的所有权.