【问题标题】:What is the point of @property and @synthesize?@property 和 @synthesize 的意义何在?
【发布时间】:2010-07-03 00:33:01
【问题描述】:

我一直没弄明白,也没有网站能解释得够清楚……@property@synthesize 的目的到底是什么?

提前致谢!

【问题讨论】:

    标签: iphone ios4 objective-c-2.0


    【解决方案1】:

    Objective-C Runtime Programming Guide: Declared Properties

    @property 为要实现的公共属性声明 getter 和 setter 方法。例如这个属性声明:

    @property float value;
    

    相当于:

    - (float)value;
    - (void)setValue:(float)newValue;
    

    @synthesize 为这两个访问器提供了默认实现。

    更新:上面解释了这两者的作用。它没有解释他们的目的是什么。 :-)

    • @property 向公共接口添加一个成员,该成员充当类客户端的数据变量,但使用方法进行读取和写入。这使您可以更好地控制客户端和代码之间交换的数据,例如,您可以对代码给出的值进行扩展验证。
    • @synthesize 允许您不显式编写将由客户端调用的代码,而实际上您自己将属性视为数据变量。

    【讨论】:

    • 我不知道我是否完全理解这一点......为什么不直接做:value = 0.0;
    • 答案部分错误。 @property 声明一个 getter(和/或 setter)。它还声明了 getter/setter 行为的某些方面(例如,保留、复制、分配、非原子)。 @synthesize 提供基于 @property 的访问器的默认实现。这些都不允许您将属性视为数据成员,就像写出标准方法声明和定义一样。
    • 从访问类的客户端代码来看,属性作为数据成员,具有数据成员的语义。是的,@property 确实声明了访问器行为的某些方面,我觉得我可以放心地省略,因为它在我链接到的完整文档中进行了描述。
    • 链接失效(并且 cmets 必须超过 15 个字符)
    【解决方案2】:

    编译器将“@”符号解释为指令。这是 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 方法中的输入值)。

    【讨论】:

      【解决方案3】:

      希望对你有帮助。

      @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

      【讨论】:

        【解决方案4】:

        只是一个简单的示例,说明您可能不想只使用“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 并相应地构建方法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-22
          • 1970-01-01
          • 1970-01-01
          • 2011-07-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多