代码之家  ›  专栏  ›  技术社区  ›  esqew

@property和@synthesis的意义是什么?

  •  5
  • esqew  · 技术社区  · 14 年前

    我还没弄清楚,也没有网站能解释清楚…目的究竟是什么 @property @synthesize ?

    事先谢谢!

    4 回复  |  直到 9 年前
        1
  •  13
  •   Franci Penov    9 年前

    Objective-C Runtime Programming Guide: Declared Properties

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

    @property float value;
    

    相当于:

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

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

    更新 :上面解释了这两种方法的作用。它不能解释他们的目的是什么。-)

    • @房产 向公共接口中添加一个成员,该成员充当类客户机的数据变量,但使用方法进行读写。这样可以更好地控制客户机和代码之间交换的数据,例如,您可以对代码给出的值进行扩展验证。
    • @合成 允许您不显式地编写将由客户机调用的代码,并将该属性本身视为数据变量。
        2
  •  3
  •   falconcreek    14 年前

    编译器将“@”符号解释为指令。这是C语言的目标C“添加”之一。当您声明@property,然后声明@synthesis时,您将指示编译器为您创建getter和setter的指令和相应符号。记住,在C语言中,“=”运算符表示“assign”。在Objective-C扩展所提供的OO上下文中,大多数时候我们都在与 指针 (又称参考)到ISA数据结构(Objective-C中的类)。

    在objective-c 2.0之前,所有getter和setter方法都必须由开发人员为每个属性进行编码,在大多数情况下,这些属性都是复制/粘贴代码。要完全符合kvc/kvo,需要 很多 非常冗长的代码…willAccessValueForkey、didUpdateValueForkey语句等。当您使用@property/@合成语法时,新编译器会自动为您添加这些语句。这对开发人员来说是一个巨大的生产力提升。添加到语言中的点语法在社区中有点争议,因为这隐藏了 魔术 编译器代表您解释 object.property = anotherObject.property; 语句作为 [object setProperty:[anotherObject property]];

    来自其他答案中引用的Apple文档

    属性声明属性

    您可以使用表单@property(attribute[,attribute2,…)来用属性修饰属性。与方法一样,属性的作用域也是它们的封闭接口声明。对于使用逗号分隔的变量名列表的属性声明,属性属性应用于所有命名属性。

    如果使用@synthesis指令告诉编译器创建访问器方法,则它生成的代码与关键字指定的规范匹配。如果您自己实现访问器方法,那么应该确保它与规范匹配(例如,如果您指定了copy,那么必须确保您确实复制了setter方法中的输入值)。

        3
  •  3
  •   Ashvin    12 年前

    我希望这对你有帮助。

    @属性和@synthesis用于将对象或变量访问到另一个类中。

    下面是一个小例子: 这是头等舱

    #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); 
    }
    

    这样您就可以访问ClassB中的firstname和lastname。

    他们打印:

    2012-05-25 14:38:10.766我的例子[8751:c07]firstname=ashvin 2012-05-25 14:38:10.768 MyExample[8751:c07]lastname=Ajadiya

        4
  •  0
  •   v01d    14 年前

    只是一个简单的例子,说明为什么您可能不想只做“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中执行非常强大的操作,synthesis用于反复发生的那些操作,如保留属性等。编译时,它会查看@property并相应地构建方法。