我不明白在代码中声明实例变量的方法

时间:2016-08-07 12:25:29

标签: objective-c properties instance-variables

我不太了解声明实例变量和属性的方式。有人可以详细解释下面两个代码的区别吗?在第二种方法中,如果我对_name使用instance variable,它是否与在第一个代码中声明name的方式相同?谢谢!

第一个代码:

//  OrderItem.h
#import <Foundation/Foundation.h>

@interface OrderItem : NSObject

{

  @public NSString *name;

}

-(id) initWithItemName: (NSString *) itemName;

@end


//  OrderItem.m
#import "OrderItem.h"

@implementation OrderItem

-(id) initWithItemName: (NSString *) itemName {

     self = [super init];

      if (self) {

          name = itemName;

         NSLog(@"Initializing OrderItem");
   }

     return  self;

   }

@end

第二代码:

//  OrderItem.h
#import <Foundation/Foundation.h>

@interface OrderItem : NSObject

 @property (strong,nonatomic) NSString *name;

-(id) initWithItemName: (NSString *) itemName;

@end


//  OrderItem.m
#import "OrderItem.h"

@implementation OrderItem

-(id) initWithItemName: (NSString *) itemName {

     self = [super init];

      if (self) {

          _name = itemName;

         NSLog(@"Initializing OrderItem");
   }

     return  self;

   }

@end

2 个答案:

答案 0 :(得分:1)

在第一种情况下,您已经声明了一个实例变量(在Objective-C中通常称为 ivar )。

在第二种情况下,您已声明了一个属性。属性是一组两个方法,一个getter和一个setter,通常使用点表示法访问,例如nssm.exe install service_name c:\your_nodejs_directory\node.exe c:\your_application_directory\server.js net start service_name 。但是,会自动为名称为self.name的属性合成 ivar 。该实例变量就是您在_name中访问的内容。

您实际上可以使用init更改ivar的名称或根本不更改它(如果您手动声明getter和setter,则不会合成ivar。)

Objective-C属性是一个相当复杂的主题,所以如果您不立即理解它,请不要担心。

答案 1 :(得分:1)

属性是公共的,这意味着其他类可以读取和写入它们(即使是不是声明属性的类的子类的类)。除此之外,属性还提供 getter setter 方法(mutator方法)。每次访问属性时都会调用属性的getter

NSString *aName = self.name;

每次写入或分配到属性时都会访问setter。

self.name = @"Some name";

实例变量(或ivars)默认情况下仅对声明它的类及其子类(也称为由其类封装)可见。您可以在将关键字@public添加到ivar声明中时更改此默认行为。