目标C中界面下的声明

时间:2015-04-28 21:30:04

标签: ios objective-c

我正在研究Big Nerd Ranch的Objective C编程书。 我看到了如下代码:

@interface BNREmployee : BNRPerson
{
    NSMutableArray *_assets;
}


@property (nonatomic) unsigned int employeeID;
@property (nonatomic) unsigned int officeAlarmCode;
@property (nonatomic) NSDate *hireDate;
@property (nonatomic, copy) NSArray *assets;

-(double)yearsOfEmployment;
-(void)addAsset:(BNRAsset *)a;
-(unsigned int)valueOfAssets;

在此代码中,为什么要在界面下声明NSMutableArray *_assets?这与宣称它是一种财产有什么不同,它的用途是什么?

最后,我看到一个属性中有一个NSArray *assets。这与NSMutableArray *_assets基本相同吗?

3 个答案:

答案 0 :(得分:2)

在这里,您要声明一个名为_assets的实例变量:

@interface BNREmployee : BNRPerson {
    NSMutableArray *_assets;
}

您现在可以在类的实现中使用此变量:

_assets = @[ @1, @2, @4 ].mutableCopy;
NSLog(@"The Answer is %@.", _assets[0]);

但是,实例变量在Objective-C中是私有的,如果您不想要任何其他内容来访问它,这是很好的。但是,如果您需要其他课程来访问和/或更改assets

,该怎么办?

在大多数情况下,您需要使用iVar属性。

通过使用属性,我们自动创建setter和getter,这意味着可以覆盖它以进行自定义并由其他类使用(如果放在标题.h文件中)。

@property (nonatomic, assign) NSMutableArray *assets;

NSMutableArray只是NSArray的可变(可编辑)对应物,它意味着我们可以通过插入新的,删除旧的和移动索引来修改数组的值。

答案 1 :(得分:1)

我不确定他们为什么这样做,但作为一般的良好做法,你不应该自己这样做。应该为该类的公共接口保留头文件。只是把那个类的调用者和用户真正需要看到的东西放在那里,通常是属性,方法和extern常量。

然后问题就变成了实现是使用属性还是常规实例变量。这主要是基于偏好的。有些人声明了一切的属性,根本不使用普通的ivars。其他人在他们想要为有问题的变量声明自定义setter / getter时,只使用ivars作为所有内容和属性。我在后一个阵营,但如果一切都只是一个财产,那么可以说更清晰,更容易阅读。

修改

我误读了代码。我上面所说的通常是正确的,但是他们在那里做的是暴露出与底层数据不同的API。现在编辑我的答案。

当您声明没有自定义@synthesize的属性并且没有覆盖setter和getter(如果它们适用)时,将使用前面的下划线创建基础变量。他们在这里做的是在公共API中返回NSArray以确保在内部使用NSMutableArray时不修改内部变量。

我会说,一般情况下,变量声明(NSMutableArray *_assets;)仍然应该放在实现文件中。调用者可能不需要知道它在引擎盖下是可变的。

实际上已经存在许多现有问题。这是一个包含多个搜索查询的搜索查询: https://stackoverflow.com/search?q=mutable+ivar+immutable+property

答案 2 :(得分:0)

关键思想是实例变量的类型与属性声明的类型不同:它是可变的,而属性声明是不可变的。