目标C中界面下的声明

时间:2022-09-07 09:20:46

I am studying Big Nerd Ranch's Objective C programming book. I saw a code like below:

我正在研究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;

In this code, why do you declare NSMutableArray *_assets under the interface? How is this different than declaring it as a property, and what purpose does it serve?

在这段代码中,为什么在接口下声明NSMutableArray * _assets?这与将其宣布为财产有何不同,它的目的是什么?

Lastly, I see there is a NSArray *assets in a property. Is this basically same as NSMutableArray *_assets?

最后,我看到房产中有一个NSArray *资产。这与NSMutableArray * _assets基本相同吗?

3 个解决方案

#1


1  

I'm not sure why they did that but as a general good practice, you shouldn't do that yourself. The header file should be reserved for the public interface of the class. Only put things in there that callers and users of that class actually need to see, which will generally be properties, methods, and perhaps extern constants.

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

Then the question becomes in the implementation whether to use a property or a regular instance variable. This is largely preference based. Some people declare properties for everything and don't use plain ivars at all. Others use ivars for everything and only properties when they want to declare a custom setter/getter for the variable in question. I am in the latter camp but it is arguable that is clearer and easier to read if everything is just a property.

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

edit

I misread the code. What I say above stands normally, but what they are doing there is exposing an API that is different than the underlying data. Editing my answer now.

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

When you declare a property without a custom @synthesize and without having overridden both the setter and getter if they are applicable, an underlying variable is created with the underscore in front. What they are doing here is returning an NSArray in the public API to ensure the internal variable is not modified while internally using an NSMutableArray.

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

I would say that in general though, that variable declaration (NSMutableArray *_assets;) should still go in the implementation file. The caller should probably not need to know that it is mutable under the hood.

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

There are actually a lot of existing questions touching upon this already. Here is a search query with a number of them: https://*.com/search?q=mutable+ivar+immutable+property

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

#2


2  

Here, you're declaring an instance variable named _assets:

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

@interface BNREmployee : BNRPerson {
    NSMutableArray *_assets;
}

You can now use this variable within the implementation of your class:

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

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

However, instance variables are private in Objective-C, which is good if you do not want anything else to access it. However what if you need other classes to be able to access and/or change assets?

但是,实例变量在Objective-C中是私有的,如果您不想要任何其他内容来访问它,这是很好的。但是,如果您需要其他类来访问和/或更改资产,该怎么办?

For the most part you will want to use a property iVar.

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

By using a property we automatically create the setters and getters, meaning this can be overridden for customization and used by other classes (if placed in the header .h file).

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

@property (nonatomic, assign) NSMutableArray *assets;

NSMutableArray is just the mutable (editable) counterpart to NSArray, it means we can modify the values of the array by inserting new ones, deleting old ones and moving the indexes around.

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

#3


0  

The key idea is that instance variable has a different type than the property declaration: it is mutable, whereas the property declaration is immutable.

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

#1


1  

I'm not sure why they did that but as a general good practice, you shouldn't do that yourself. The header file should be reserved for the public interface of the class. Only put things in there that callers and users of that class actually need to see, which will generally be properties, methods, and perhaps extern constants.

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

Then the question becomes in the implementation whether to use a property or a regular instance variable. This is largely preference based. Some people declare properties for everything and don't use plain ivars at all. Others use ivars for everything and only properties when they want to declare a custom setter/getter for the variable in question. I am in the latter camp but it is arguable that is clearer and easier to read if everything is just a property.

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

edit

I misread the code. What I say above stands normally, but what they are doing there is exposing an API that is different than the underlying data. Editing my answer now.

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

When you declare a property without a custom @synthesize and without having overridden both the setter and getter if they are applicable, an underlying variable is created with the underscore in front. What they are doing here is returning an NSArray in the public API to ensure the internal variable is not modified while internally using an NSMutableArray.

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

I would say that in general though, that variable declaration (NSMutableArray *_assets;) should still go in the implementation file. The caller should probably not need to know that it is mutable under the hood.

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

There are actually a lot of existing questions touching upon this already. Here is a search query with a number of them: https://*.com/search?q=mutable+ivar+immutable+property

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

#2


2  

Here, you're declaring an instance variable named _assets:

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

@interface BNREmployee : BNRPerson {
    NSMutableArray *_assets;
}

You can now use this variable within the implementation of your class:

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

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

However, instance variables are private in Objective-C, which is good if you do not want anything else to access it. However what if you need other classes to be able to access and/or change assets?

但是,实例变量在Objective-C中是私有的,如果您不想要任何其他内容来访问它,这是很好的。但是,如果您需要其他类来访问和/或更改资产,该怎么办?

For the most part you will want to use a property iVar.

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

By using a property we automatically create the setters and getters, meaning this can be overridden for customization and used by other classes (if placed in the header .h file).

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

@property (nonatomic, assign) NSMutableArray *assets;

NSMutableArray is just the mutable (editable) counterpart to NSArray, it means we can modify the values of the array by inserting new ones, deleting old ones and moving the indexes around.

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

#3


0  

The key idea is that instance variable has a different type than the property declaration: it is mutable, whereas the property declaration is immutable.

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