当我尝试为OS 3编译我的应用程序时遇到以下错误:
错误:访问者类型与属性类型
不匹配错误是我尝试访问的属性,定义如下:
NSMutableArray *myArray
@property (readonly,nonatomic) NSArray* myArray;
该属性在实现文件中是@synthesized。
这在OS 2.2.1中运行得很好,但不是OS 3.0
自己编写getter方法解决了这个问题。
是否有人知道OS 2.2.1和3.0之间对objective-c的更改? 有没有关于这些变化的文件?
API changes document似乎不包含任何有关此问题的内容。
编辑
当您尝试访问该属性时会发生错误,例如
NSArray *anArray = myClass.myArray;
正如我上面提到的,我找到了一个解决方法:自己编写getter方法,但是我真正关注的是来自apple的一些文档,解释了这个更改以及与API无关的任何其他更改。
感谢您的帮助
答案 0 :(得分:17)
这是编译错误。
虽然您没有完全指定它,但我希望您的代码如下所示:
@interface Foo : NSObject {
NSMutableArray *objects;
}
@property (readonly, copy) NSArray *objects;
@end
@implementation Foo
@synthesize objects;
@end
遗憾的是,编译器在objects
属性的声明与objects
实例变量的声明之间混淆了。请记住,Objective-C中的属性和实例变量是不同的东西;属性可以由实例变量支持,但它实际上是类的公共接口的一部分。
您可以通过更改代码来清楚地将实例变量的定义与属性的定义分开,例如通过为实例变量的名称添加前缀来解决此问题:
@interface Foo : NSObject {
NSMutableArray *_objects;
}
@property (readonly, copy) NSArray *objects;
@end
@implementation Foo
@synthesize objects = _objects;
@end
这样编译器就不会对像self.objects
这样的表达式中的属性与实例变量感到困惑(无论如何它都不应该,但显然是这样)。
只是为了阻止不可避免的响应:Apple 不保留实例变量的下划线前缀。它保留用于方法。无论如何,如果您不喜欢下划线,请随意使用其他前缀。
答案 1 :(得分:5)
编辑:在同行评审发现缺少原始答案后删除。请阅读Chris Hanson对此事的评论。我将其余的留在这里因为我认为它仍然有效。
请注意,即使您将属性类型声明为NSArray
,返回的对象仍然是NSMutableArray
,并为其定义了可变方法 。以这种方式声明属性不可以防止有人意外地改变数组。
如果你想确定返回的数组是不可变的,你可以在原始示例中声明属性,然后滚动自己的访问器:
- (NSArray *)myArray { return [NSArray arrayWithArray:myArray]; }
请注意,这将返回未保留的NSArray
。如果需要持久存在,则由调用者来取得对象的所有权。
答案 2 :(得分:4)
您看到错误,因为XCode现在正在发出以前没有发生的事情的警告和错误......
我认为最多应该警告做你正在做的事情,我理解你试图将数组呈现为外部世界不可变但在课堂上有可变性。您可能需要考虑使用不同名称的不同访问器,以便专门返回可变数组。
答案 3 :(得分:1)
它仍然是Objective-C 2.0;考虑到这种类型改变错误,编译器可能只是稍微更新一下。它几乎应该是一个错误。至少它应该警告你,你可能并不是指你写的东西。然后你可以施放东西以使它不警告你,你不能用@synthesize
语句来做。
我只是将你的代码和一个综合语句粘贴到我的控制器中,我没有得到任何错误或警告。它建好了。现在我将基本SDK设置为“Simulator 3.0”,并将构建设置为“Simulator 3.0 Debug”。这个项目已经在2.2.1 SDK中启动了,我昨天刚刚安装了3.0 SDK; Xcode是版本3.1.3。
更新:哦,我发现实际上尝试设置属性是您收到错误的地方。
self.myArray = [NSArray arrayWithObject:@"foo"];
显然,你不能@synthesize
这种行为,必须编写自己的访问者。
- (NSArray*)myArray {
return [NSArray arrayWithArray:myArray];
}
- (void)setMyArray:(NSArray*) pMyArray {
myArray = [NSMutableArray arrayWithArray:pMyArray];
}
填写这些访问者,没有消息消失,所以我不得不改变访问权限:
[self setMyArray:[NSArray arrayWithObject:@"foo"]];
使用没有自定义访问器的上述语法也不起作用。
PS哇,是否有人因为你无法复制消息气泡或构建结果窗口中的文本而烦恼?答案 4 :(得分:0)
所以这实际上与@synthesize调用有关,该调用不喜欢将NSMutableArray暴露为NSArray - 为什么不实现getMethod。
实际上考虑它必须是不满意的set方法 - 你将无法将NSArray设置为NSMutableArray。
答案 5 :(得分:0)
你的问题是:
是否有人知道OS 2.2.1和3.0之间对objective-c的更改?
这些更改是否有任何文档?
明确的答案是:
1)语言规范没有有意改变,但编译器和其他开发人员工具发生了变化。克里斯和他的同事是这些变化的专家。
2)可能不是,因为任何更改都是无意的,或者是为了更好地匹配文档的行为。
你不应该如此迅速地将克里斯的回答视为“猜测”。 Chris使用Apple的开发人员工具。你可能会得到另一个你喜欢的答案,但你不会得到更专业的答案。