【发布时间】:2010-07-03 00:33:01
【问题描述】:
我一直没弄明白,也没有网站能解释得够清楚……@property 和@synthesize 的目的到底是什么?
提前致谢!
【问题讨论】:
标签: iphone ios4 objective-c-2.0
我一直没弄明白,也没有网站能解释得够清楚……@property 和@synthesize 的目的到底是什么?
提前致谢!
【问题讨论】:
标签: iphone ios4 objective-c-2.0
Objective-C Runtime Programming Guide: Declared Properties
@property 为要实现的公共属性声明 getter 和 setter 方法。例如这个属性声明:
@property float value;
相当于:
- (float)value;
- (void)setValue:(float)newValue;
@synthesize 为这两个访问器提供了默认实现。
更新:上面解释了这两者的作用。它没有解释他们的目的是什么。 :-)
@property 向公共接口添加一个成员,该成员充当类客户端的数据变量,但使用方法进行读取和写入。这使您可以更好地控制客户端和代码之间交换的数据,例如,您可以对代码给出的值进行扩展验证。 @synthesize 允许您不显式编写将由客户端调用的代码,而实际上您自己将属性视为数据变量。【讨论】:
编译器将“@”符号解释为指令。这是 Objective-C 对 C 语言的“补充”之一。当您声明 @property 然后 @synthesize 时,您是在指示编译器为您创建 getter 和 setter 的指令和相应的符号。请记住,在 C 语言中,“=”运算符表示“赋值”。大多数时候,在 Objective-C 扩展提供的 OO 上下文中,我们使用 pointers(又名引用)到 isa 数据结构(Objective-C 中的类)。
在 Objective-C 2.0 之前,所有的 getter 和 setter 方法都必须由开发人员为每个属性编码,在大多数情况下是复制/粘贴代码。要完全兼容 KVC/KVO,需要很多非常繁琐的代码... willAccessValueForKey、didUpdateValueForKey 语句等,当您使用 @property/@synthesize 语法时,新编译器会自动为您添加这些语句。这对开发人员来说是一个巨大的生产力提升。该语言的点语法添加在社区中更具争议性,因为这隐藏了编译器正在代表您将object.property = anotherObject.property; 语句解释为[object setProperty:[anotherObject property]]; 的魔术
来自其他答案中引用的 Apple 文档
属性声明属性
您可以使用@property(attribute [, attribute2, ...]) 形式用属性装饰属性。与方法一样,属性的范围仅限于其封闭的接口声明。对于使用逗号分隔的变量名列表的属性声明,属性属性适用于所有命名属性。
如果您使用@synthesize 指令告诉编译器创建访问器方法,它生成的代码与关键字给出的规范相匹配。如果您自己实现访问器方法,则应确保它与规范匹配(例如,如果您指定复制,则必须确保复制 setter 方法中的输入值)。
【讨论】:
希望对你有帮助。
@property 和@synthesize 用于将对象或变量访问到另一个类中。
这是一个小例子: 这是头等舱
#import <UIKit/UIKit.h>
#import "ClassB.h"
@interface ViewController : UIViewController
@property(nonatomic, retain) NSString *FirstName;
@property(nonatomic, retain) NSString *LastName;
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
@synthesize FirstName, LastName;
- (void)viewDidLoad
{
[super viewDidLoad];
self.FirstName = @"Ashvin";
self.LastName = @"Ajadiya";
ClassB *ClassBOb = [[ClassB alloc] init];
ClassBOb.ViewCntrlrOb = self;
[ClassBOb CallMe];
}
@end
这是另一个类:
#import <UIKit/UIKit.h>
@class ViewController;
@interface ClassB : UIViewController
@property(nonatomic, retain) ViewController *ViewCntrlrOb;
-(void) CallMe;
@end
#import "ClassB.h"
#import "ViewController.h"
@interface ClassB ()
@end
@implementation ClassB
@synthesize ViewCntrlrOb;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(void) CallMe
{
NSLog(@"FirstName = %@",ViewCntrlrOb.FirstName);
NSLog(@"LastName = %@",ViewCntrlrOb.LastName);
}
这样您就可以将 FirstName 和 LastName 访问到 ClassB 中。
他们打印:
2012-05-25 14:38:10.766 MyExample[8751:c07] FirstName = Ashvin 2012-05-25 14:38:10.768 MyExample[8751:c07] LastName = Ajadiya
【讨论】:
只是一个简单的示例,说明您可能不想只使用“variable = 0”:
假设你有这个属性:
@property (nonatomic, retain) id <MyDelegate> theDelegate;
每当您用新的委托替换该委托时,您的合成 setter 和 getter 将在您每次设置时为您处理释放/保留:
self.theDelegate = newObject;
真正发生的事情是这样的:
[self setTheDelegate:newObject];
- (void)setTheDelegate:(id <MyDelegate>)anObject {
[theDelegate release];
theDelegate = [anObject retain];
}
(当然是简化了)
您可以在自己的 setter 和 getter 中做非常强大的事情,synthesize 用于那些反复发生的事情,例如保留属性等。编译时会查看您的 @property 并相应地构建方法。
【讨论】: