我不太了解声明实例变量和属性的方式。有人可以详细解释下面两个代码的区别吗?在第二种方法中,如果我对_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
答案 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声明中时更改此默认行为。