NSArray和NSMutable数组。财产的类型和ivar的类型不一样

时间:2014-08-07 17:32:30

标签: objective-c class

我正在通过Objective-C编程的大书呆子牧场指南。

第21章有一个例子和挑战,我被困扰了。 (我实际上完成了挑战,但我使用了以前的代码示例)我想真正理解我的所作所为。

它与声明NSArray类型的属性,然后将setter方法声明为类型NSMutableArray有关。谁能告诉我这里发生了什么?使用此声明“幕后”会发生什么。

@property (nonatomic copy) NSArray *assets 

这两个文件中发生了什么?请尽可能在最低级别解释。谢谢!

BNREmployee.h

@interface BNREmployee: BNRPerson
{
    NSMutableArray *_assets
}
@property (nonatomic copy) NSArray *assets 

@end 

BNREmployee.m

@implementation BNREmployee 

- (void)setAssets:(NSArray *)a
{
    _assets = [a mutableCopy]; //What did this actually do? 
}

- (NSArray *)assets
{
    return [_assets copy];
}

1 个答案:

答案 0 :(得分:0)

NSMutableArray是一个NSArray(它是一个子类),因此它只是正常分配。幕后没有什么特别的事情发生。

我可以看一下你的模型的一个例子是将BNREmployee对象分配给BNRPerson指针,该指针可以正常工作。

BNREmployee *employee = [BNREmployee new]; // or whatever initializer

BNRPerson *person = employee; // works fine, an employee IS a person

您始终可以将NSMutableArray分配给NSArray指针,但不是相反。

修改

  

“该属性具有类型NSArray,告诉其他类,如果你问   对于我的资产,你会得到一些不可变的东西。   但是,在幕后,assets数组实际上是一个实例   NSMutableArray,以便您可以在BNREmployee“

中添加和删除项目

通过将公共属性公开为不可变类型,您可以让任何潜在的调用者知道他们无法在不显式调用对象的mutator的情况下修改属性。 它还允许呼叫者知道一旦他们获得该集合,其内容将永远不会从其下面更改。这是暴露不可变属性时的标准契约。 正如下面的一条评论所指出的,可能存在返回类型是不可变的情况,但底层对象实际上是内部可变的并且可以更改,如果你还没有收到实际的不可变副本,那么好的做法是在收到对象时制作副本,例如[NSView subviews]

使实际的底层变量成为可变类型可以方便地让拥有类在内部轻松修改它。在功能上,您可以通过使其成为常规NSArray来完成同样的事情,并在您想要更改其内容(例如array = [array arrayByAddingObject:object])时不断重新创建它。这当然比仅修改可变实例要慢。