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

时间:2009-06-19 18:21:12

标签: iphone objective-c iphone-sdk-3.0

当我尝试为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无关的任何其他更改。

感谢您的帮助

6 个答案:

答案 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的开发人员工具。你可能会得到另一个你喜欢的答案,但你不会得到更专业的答案。