在进入 Objective-C 编程时,我一直在努力解决的一件事是了解如何操作属性。与我习惯使用的脚本语言相比,我使用适当的编码语言可能超出了我的舒适区,因此在头文件和实现文件中声明内容让我有些困惑。
假设我有一个字符串。我希望在该字符串中添加一些文本。我在头文件中声明什么以及在实现文件中做什么以使其正常工作,以及@property 和@synthesize 是什么?
在进入 Objective-C 编程时,我一直在努力解决的一件事是了解如何操作属性。与我习惯使用的脚本语言相比,我使用适当的编码语言可能超出了我的舒适区,因此在头文件和实现文件中声明内容让我有些困惑。
假设我有一个字符串。我希望在该字符串中添加一些文本。我在头文件中声明什么以及在实现文件中做什么以使其正常工作,以及@property 和@synthesize 是什么?
在 Objective-C 2.0 之前的糟糕日子里,为实例变量编写 getter 和 setter 是很常见的,例如
@interface Foo : NSObject
{
@private
id foo;
}
-(void) setFoo: (id) newFoo;
-(id) foo;
@end
@implementation Foo
// need dealloc to release foo too.
-(void) setFoo: (id) newFoo
{
[newFoo retain];
[foo release];
foo = newFoo;
}
-(id) foo
{
return foo;
}
@end
这只是在单线程环境中。多线程应用程序需要更多的东西。
属性为上述内容提供了简洁的简写。@property 替换了接口中的两个声明,并为调用者提供了有关 getter 和 setter 语义的更好提示。它还允许您@synthesize 访问器,以便编译器自动为它们生成代码(您不必@synthesize它们,如果需要,您可以提供自己的实现)。以上都可以换成
@interface Foo : NSObject
{
@private
id foo;
}
@property (nonatomic, retain) id foo;
@end
@implementation Foo
// need dealloc to release foo too.
@synthesize foo;
@end
这节省了相当多的输入,但您也可以从界面中看到 setFoo: 将保留其新值,并且该属性在多线程环境中使用(设置或获取)是不安全的(没有其他一些锁定机制)。
@property
- 声明一个带有访问和内存修饰符的属性。属性可以是只读或读写、非原子或原子(线程安全)、分配/保留/复制管理。实际上,您可以像我们在 Tiger 时代所做的那样声明简单的 getter 和 setter 方法,但声明 a@property
将帮助您随时识别属性的所有方面,而无需检查实现。
@synthesize - 如果您需要一个简单的属性,而在 getter 和 setter 中没有任何复杂的工作,则可以简化工作。它根据 的定义定义了一个默认实现@property
。
最后,关于字符串的问题。如果您正在寻找简单的东西,例如,属性将无济于事myObj.string += "abc"
。它不是 Objective-C 风格,无论有没有属性,你都会做类似myObj.string = [[myObj string] stringByAppendingString:@"abc"]
或[[myObj string] appendString:@"abc"]
取决于字符串对象的可变/不可变性质的事情。
作为底线:在一篇文章中解释所有内容是一个相当大的话题。我建议您阅读 Apple 文档,或者购买一本有关 Objective-C 的书。Aaron Hillegass 写了一篇——对于任何 Objective-C 和 Mac OS X 初学者来说都是一个好的开始。