Designing the Model Layer
设计模型层
Every app handles data of some kind. In this tutorial, the BirdWatching app handles a list of bird-sighting events. To follow the Model-View-Controller (MVC) design pattern, you need to create classes that represent and manage this data.
每个app处理某种数据。在本教程中,BirdWatching app处理bird-sighting事件的列表。按照(MVC)设计模式,你需要创建代表和管理这个数据的类。
In this chapter, you design two classes. The first represents the primary unit of data that the app handles. The second class creates and manages instances of this data unit. These classes, together with the master list of data, make up the model layer of the BirdWatching app.
在本章中,你定义两个类。第一个类代表app处理的主数据单元。第二个类创建和管理这个数据单元的实例。这些类,以及master 列表的数据,组成了BirdWatching app 的模型层。
Note: The Master-Detail template defines an array containing the placeholder data. You add this data when you click the Add button (+) in the default app. In a later step, you’ll replace the template-provided array with the classes that you create next.
注意:主-从模型定义了一个数组,其中包含了占位符数据。当你在默认app中点击(+)按钮的时候,你添加了这个数据。在接下来的步骤中,你将在创建一个类来代替模型提供的数组。
Determine the Unit of Data and Create a Data Object Class
确定数据单元并创建数据对象类
To design a data object class, first examine the app’s functionality to discover what units of data it needs to handle. For example, you might consider defining a bird class and a bird-sighting class. But to keep this tutorial as simple as possible, you’ll define a single data object class—a bird-sighting class—that contains properties that represent a bird name, a sighting location, and a date.
想要设计数据对象类,首先要确定app的功能以便了解什么样的数据单元需要被处理。例如,你或许考虑定义一个鸟的类和一个bird-sighting的类。但本教程为了保持尽可能的简单,你将定义一个单一的数据对象类——bird-sighting类——它包含代表鸟的名字、观察位置以及日期的属性。
To produce bird-sighting objects that the BirdWatching app can use, you need to add a custom class to your project. Because the bird-sighting object needs very little functionality (for the most part, it simply needs to behave as an Objective-C object), create a new subclass of NSObject.
为了生成BirdWatching app 能够使用的bird-sighting对象,你需要添加一个自定义的类到你的工程中。因为bird-sighting对象需要非常少的功能(基本上,它仅仅相当于一个Objective-C对象),创建一个新的NSObject的子类。
To create the class files for the bird-sighting object
为bird-sighting 对象创建类文件
1.In Xcode, choose File > New > File (or press Command-N).
在Xcode中,选择File > New > File (或按Command-N)
2.In the dialog that appears, select Cocoa Touch in the iOS section at the left side of the dialog.
在显示的对话窗中,在对话框的左侧的iOS 区域中选择Cocoa Touch。
3.In the main area of the dialog, select Objective-C class and then click Next.
在对话框的主区域,选择Objective-C类并点击Next。
4.In the next pane of the dialog, type the name BirdSighting in the Class field, choose NSObject in the “Subclass of” pop-up menu, and click Next.
在接下来的对话框中,在Class field中键入名字BirdSighting,在“Subclass of”弹出菜单中选择NSObject,并点击Next。
By convention, the name of a data object class is a noun because it names the thing that the class represents.
通常来说,数据对象类的名字是一个名词,因为它的名字是这个类的代表。
5.In the next dialog that appears, choose the BirdWatching folder in the Group pop-up menu:
在接下来显示的对话框中,在Group的弹出菜单中选择BirdWatching文件夹。
6.In the dialog, click Create.
在对话框中,选择Create。
Xcode creates two new files, named BirdSighting.h and BirdSighting.m, and adds them to the BirdWatching folder in the project. By default, Xcode automatically opens the implementation file (that is, BirdSighting.m) in the editor area of your workspace window.
Xcode 创建了两个新的文件,BirdSighting.h和BirdSighting.m,并且添加他们到工程的BirdWatching文件夹中。默认情况下,Xcode自动的在你的工作空间窗口打开实现文件(BirdSighting.m)。
The BirdSighting class needs a way to hold the three pieces of information that define a bird sighting. In this tutorial, you use declared properties to represent these items. When you use declared properties, you let the compiler synthesize accessor methods for each one.
BirdSighting类需要有处理定义bird sighting的三部分信息的方法。在本教程中,你使用声明的属性来表示这些项。当你使用声明的属性,你让编译器为每个属性合成访问方法。
The BirdSighting class also needs to initialize new instances of itself with information that represents an individual bird sighting. To accomplish this, add a custom initializer method to the class.
BirdSighting类还需要使用代表具体的观鸟信息初始化它自身的新对象。为此,添加一个自定的方法到类中。
First, declare the properties and the custom initialization method in the header file.
首先,在头文件中声明属性并自定义初始化方法。
To declare properties and a custom initializer method in BirdSighting.h
在BirdSighting.h中声明属性和自定义初始化方法
1.Select BirdSighting.h in the project navigator to open it in the editor area.
在工程导航器中选择BirdSighting.h,把它在编辑区域中打开。
2.Add the following code between the @interface and @end statements:
在@interface和@end之间添加如下代码:
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *location;
@property (nonatomic, strong) NSDate *date;
3.Add the following code line after the third property definition:
在三个属性定义的后面添加如下代码:
-(id)initWithName:(NSString *)name location:(NSString *)location date:(NSDate *)date;
To implement the custom initializer method
实现自定义初始化方法
1.In the project navigator, select BirdSighting.m.
在工程导航器中选择BirdSighting.m。
When BirdSighting.m opens in the editor, Xcode displays a warning icon—in the activity viewer in the middle of the toolbar and in the bar above the editor. Click the warning button in the navigator selector bar to view the warning (the warning button is the middle button in the navigator selector bar). You should see something like this:
当BirdSighting.m在编辑器中打开的时候,Xcode位于编辑器顶部的工具栏的中间位置的活动查看器显示警告图标。点击在导航器选择器栏中的警告按钮,显示警告(警告按钮位于导航器选择器栏的中间位置)。你应该可以看到如下的内容:
In this case, Xcode is reminding you that the implementation of the BirdSighting class is incomplete because you haven’t implemented the initWithName method. You fix this problem next.
在这种情况下,Xcode提醒你,BirdSighting类的实现不完整,因为你没有实现initWithName方法。接下来你要解决这个问题。
2.In the code editor, between the @implementation and @end statements in BirdSighting.m, begin typing the initWithName method and let code completion finish it.
在代码编辑器中,在BirdSighting.m文件中的@implementation语句和@end语句之间,开始键入initWithName方法并且让代码完全完成。
Code completion is especially useful when entering method signatures because it helps you avoid common mistakes, such as mixing the order of parameters. When you start typing -(id)i you should see something like this:
代码自动完成输入在当你输入方法名字的时候特别有用,因为它帮助你避免一些常见的错误,例如混淆了参数的顺序。当你键入 -(id)i的时候,你应该看到如下的情况:
When you press Return, Xcode adds the highlighted code-completion suggestion to your file. If the highlighted suggestion is not the one you want, use the Arrow keys to highlight a different one.
当你按下回车键,Xcode添加高亮的建议来完成代码到你的文件中。如果高亮建议没有你需要的,使用箭头键来高亮显示不同的代码。
A method requires an implementation block—which is not included in the completed method signature—so Xcode displays a couple of problem indicators. You can ignore these indicators because you add the implementation code next.
发发要求一个实现代码块——它不包含在完成方法的建议代码中——所以Xcode显示几个问题的指示。你能忽略折现指示,因为你要在下一步添加这些实现代码。
3.Implement the initWithName method by entering the following code after the method signature:
通过在方法的后面输入下面的代码来实现initWithName方法。
{
self = [super init];
if (self) {
_name = name;
_location = location;
_date = date;
return self;
}
return nil;
}
After you enter all the code in this step, the warning and problem indicators disappear.
在你键入所有的代码后,警告就会消失。
Notice that the initWithName method uses versions of the property names that begin with an underscore (the _name, _location, and _date symbols refer to the instance variables that these properties represent). By convention, the underscore serves as a reminder that you shouldn’t access instance variables directly. In almost all of your code, you should use the accessor methods—such as self.name—to get or set an object’s properties. The only two places where you should not use accessor methods are in init methods—such as initWithName—and in dealloc methods.
注意,在initWithName方法中使用的属性名字的版本都开始于一个下划线(_name,_location和_date符号所指的实例变量代表了它们的属性)。按照惯例,下划线起到提醒你不要直接访问实例变量的作用。在几乎所有的代码中,你应该使用访问方法——例如self.name——来得到或获取对象的属性。只有在两种情况下你不应该使用访问方法,一种是在init 方法中(例如initWithName),另一个是在dealloc方法中。
From an academic perspective, avoiding the direct access of instance variables helps preserve encapsulation, but there are also a couple of practical benefits:
从学术的角度来看,避免直接访问实例变量帮助保持封装,但也有一些实际的好处:
Some Cocoa technologies (notably key-value coding) depend on the use of accessor methods and on the appropriate naming of the accessor methods. If you don’t use accessor methods, your app may be less able to take advantage of standard Cocoa features.
一些Cocoa技术(尤其是 键值编码)取决于使用访问方法和适当的访问方法命名。如果你不适用访问方法,你的app可能不能利用标准的Cocoa特性。
Some property values are created on demand. If you try to use the instance variable directly, you may get nil or an uninitialized value. (A view controller’s view is a good example of a property value that’s created on demand.)
一些属性值是在需要的时候被创建的。如果你试图直接使用实例变量,你或许得到一个nil值或是一个没有初始化的值。(视图控制器的视图是一个很好的例子。)
(If you’re interested, you can read more about encapsulation in “Storing and Accessing Properties” in Cocoa Fundamentals Guide.)
(如果你有兴趣,你可以在Cocoa基本指南中的“Storing and Accessing Properties”里读到更多的关于封装的内容。)
The BirdSighting class is one part of the model layer in the BirdWatching app. To preserve the BirdSighting class as a pure representation of a model object, you must also design a controller class to instantiate new BirdSighting objects and control the collection that contains them. A data controller class allows other objects in the app to access individual BirdSighting objects and the master list without needing to know anything about how the data model is implemented. You create the data controller class in the next step.
BirdSighting类是BirdWatching app模型层的一部分。想要保持BirdSighting类作为纯粹的模型对象的表示,你必须设计一个控制器类来实例化新的BirdSighting对象,并控制集合包含它们。一个数据控制器类允许app中的其他对象访问具体的BirdSighting对象,而主列表不需要知道数据模型时如何实现的。接下来你将创建数据控制器类。
Create a Data Controller Class
创建数据控制器类
A data controller class typically handles the loading, saving, and accessing of data for an app. Although the BirdWatching app does not access a file to load or store its data, it still needs a data controller to create new BirdSighting objects and manage a collection of them. Specifically, the app needs a class that:
数据控制器类通常处理加载、保存以及访问app的数据。尽管BirdWatching app没有访问文件来加载或储存它的数据,但它仍然需要数据控制器来创建新的BirdSighting对象并管理它们的集合。具体来说,app需要一个能完成如下功能的类:
Creates the master collection that holds all BirdSighting objects
创建主集合来拥有所有的BirdSighting对象。
Returns the number of BirdSighting objects in the collection
返回集合中BirdSighting对象的数目。
Returns the BirdSighting object at a specific location in the collection
返回在集合中特定位置的BirdSighting对象。
Creates a new BirdSighting object using input from the user and adds it to the collection
通过用户的输入创建新的BirdSighting对象并添加它到集合中。
As you did for the BirdSighting class, create the interface and implementation files for a new class that inherits from NSObject and add them to the project.
和BirdSighting类一样,为继承自NSObject的新类创建接口和实现文件并添加它们到工程中。
To create the data controller class files
创建数据控制器类文件
1.Choose File > New > File (or press Command-N).
选择File > New > File (或按下 Command-N)。
2.In the dialog that appears, select Cocoa Touch in the iOS section at the left side of the dialog.
在出现的对话框中,在对话框左侧的iOS部分选择Cocoa Touch。
3.In the main area of the dialog, select Objective-C class and then click Next.
子啊对话框的主区域,选择Objective-C类并点击Next。
4.In the next pane of the dialog, enter the class name BirdSightingDataController, choose NSObject in the Subclass pop-up menu, and click Next.
在接下来的对话框中,输入类的名字BirdSightingDataController,在子类弹出菜单中选择NSObject,点击Next。
5.In the next dialog that appears, choose the BirdWatching folder in the Group pop-up menu and click Create.
在接下来出现的对话框中,在Group 弹出菜单中选择BirdWatching文件夹并点击Create。
In this tutorial, the collection of BirdSighting objects is represented by an array. An array is a collection object that holds items in an ordered list and includes methods that can access items at specific locations in the list. The BirdWatching app allows users to add new bird sightings to the master list, so you use a mutable array, which is an array that can grow.
在本教程中,BirdSighting对象的集合用数组来表示。数组是一个集合对象,它持有项的有序列表,并且包含一些方法来访问表中特殊位置的项。BirdWatching app 允许用户添加新的观鸟(bird sighting)记录到主列表,所以你要使用可变数组,它能使数组增长。
The BirdSightingDataController class needs a property for the master array that it creates.
BirdSightingDataController类需要一个主数组的属性。
To declare the data controller’s property
声明数据集合的属相
1.Open BirdSightingDataController.h in the editor by selecting it in the project navigator.
在工程导航器中通过选择BirdSightingDataController.h来在编辑器中打开它。
2.Add the following code line between the @interface and @end statements:
在@interface 和@end之间添加如下代码。
@property (nonatomic, copy) NSMutableArray *masterBirdSightingList;
4.
Notice the copy attribute in the masterBirdSightingList property definition: It specifies that a copy of the object should be used for assignment. Later, in the implementation file, you’ll create a custom setter method that ensures that the array copy is also mutable.
注意masterBirdSightingList属性定义中的copy属性:它指定对象的副本将被用到任务中。稍后,在实现文件中,你将创建自定义的的setter方法,它能确保数组的副本也是可变的。
Don’t close the header file yet because you still need to add the method declarations. As mentioned at the beginning of this section, there are four tasks the data controller needs to perform. Three of these tasks give other objects ways to get information about the list of BirdSighting objects or to add a new object to the list. But the “create the master collection” task is a task that only the data controller object needs to know about. Because this method does not need to be exposed to other objects, you do not need to declare it in the header file.
不要关闭头文件,因为你仍然需要添加方法声明。正如这部分开始的时候提到的那样,数据控制器有4个任务需要实现。其中三个给其他对象提供得到信息的方法,这些信息是关于BirdSighting对象列表的活着是向列表中添加新对象的。但是,“create the master collection”只是一个解决数据控制器对象需要知道什么的任务。因为这个任务不需要接触其他对象,你不需要在头文件中声明它。
To declare the data controller’s three data-access methods
声明数据控制器的三个数据访问方法
1.Add the following code lines after the property declaration in the BirdSightingDataController.h file:
在BirdSightingDataController.h文件的属性声明下面添加如下代码行。
- (NSUInteger)countOfList;
- (BirdSighting *)objectInListAtIndex:(NSUInteger)theIndex;
- (void)addBirdSightingWithSighting:(BirdSighting *)sighting;
2.
Notice that Xcode displays red problem icons in the gutter to the left of the objectInListAtIndex and addBirdSightingWithSighting methods. When you click either indicator, Xcode displays the message “Expected a type.” This means that Xcode does not recognize BirdSighting as a valid return type. To fix this, you need to add a forward declaration, which is a statement that tells the compiler to treat a symbol as a class symbol. In effect, it “promises” the compiler that the project contains a definition for this class elsewhere.
注意Xcode在objectInListAtIndex和addBirdSightingWithSighting方法左侧的边缘沟里显示红色的问题图标。当你点击任何一个指示器,Xcode显示信息”Expected a type“。这意味着Xcode不认识BirdSighting作为有效的返回类型。为了解决这个问题,你需要添加前向声明(forward declaration),它是一个告诉编译器处理一个符号作为类符号的语句。事实上,它向编译器’承诺’包含的类在别处已经定义。
3.Add a forward declaration of the BirdSighting class.
添加BirdSighting类的前向声明。
Enter the following line between the #import and @interface statements at the beginning of the header file:
在头文件开始的地方,在#import和@interface语句之间添加如下代码。
@class BirdSighting;
4.
After a few seconds, the problem icons disappear.
等待几秒钟,问题图标消失。
You’re finished with the header file, so now open the BirdSightingDataController.m file in the editor and begin implementing the class. Notice that Xcode displays a warning indicator in the gutter next to the @implementation statement because you haven’t yet implemented the methods you declared in BirdSightingDataController.h.
你已经完成了头文件,现在在编辑器中打开BirdSightingDataController.m文件并且开始实现这个类。注意Xcode在 @implementation 语句旁边的边栏沟里显示一个警告指示器,因为你还没有实现在BirdSightingDataController.h中声明的方法。
As you determined earlier, the data controller needs to create the master list and populate it with a placeholder item. A good way to do this is to write a method that performs this task, and then call it using the data controller’s init method.
在你决定之前,数据控制器需要创建主列表并且用展位项填充它。
To implement the list-creation method
实现创建列表方法
1.Import the BirdSighting header file so that the data controller methods can refer to objects of this type.
Add the following code line after the #import "BirdSightingDataController.h" statement:
Import BirdSighting头文件,这样数据控制器方法就能引用这个类型的对象。在 #import "BirdSightingDataController.h"后面添加一下代码行。
#import "BirdSighting.h"
2.Declare the list-creation method by adding an @interface statement before the @implementation statement.
通过在@implementation 语句之前添加@interface语句来声明列表创建方法
The @interface statement should look like this:
@interface语句应如下所示:
@interface BirdSightingDataController ()
- (void)initializeDefaultDataList;
@end
3.
The @interface BirdSightingDataController () code block is called a class extension. A class extension allows you to declare a method that is private to the class (to learn more, see “Categories Extend Existing Classes” in Programming with Objective-C).
@interface BirdSightingDataController () 代码块被称为类扩展。类扩展允许声明方法,这些方法是本类的私有方法(要学习更多,参阅Programming with Objective-C中的“Categories Extend Existing Classes”)。
4.Implement the list-creation method by entering the following code lines between the @implementation and @end statements:
通过在 @implementation和@end语句之间输入如下代码行来实现列表创建方法
- (void)initializeDefaultDataList {
NSMutableArray *sightingList = [[NSMutableArray alloc] init];
self.masterBirdSightingList = sightingList;
BirdSighting *sighting;
NSDate *today = [NSDate date];
sighting = [[BirdSighting alloc] initWithName:@"Pigeon" location:@"Everywhere" date:today];
[self addBirdSightingWithSighting:sighting];
}
5.
The initializeDefaultDataList method does the following things: First, it assigns a new mutable array to the sightingList variable. Then, it uses some default data to create a new BirdSighting object and passes it to the addBirdSightingWithSighting method that you declared in “To declare the data controller’s three data-access methods,” which adds the new sighting to the master list.
initializeDefaultDataList方法做了以下事情:首先,它给sightingList变量分配了一个新的可变数组。然后,它使用一些默认的数据创建一个新的BirdSighting对象,并把它传递给addBirdSightingWithSighting方法,这个方法在“To declare the data controller’s three data-access methods”中已经被声明,它添加一个新的sighting到主列表。
Although Xcode automatically synthesized accessor methods for the master list property, you need to override its default setter method to make sure that the new array remains mutable. By default, the method signature of a setter method is setPropertyName (notice that the first letter of the property name becomes capitalized when it’s in the setter method name). It’s crucial that you use the correct name when you create a custom accessor method; otherwise, the default accessor method is called instead of your custom method.
尽管Xcode自动为主列表属性合成访问方法,但你需要覆盖默认的setter方法来确保新数组是可变数组。默认情况下,setter方法的方法名字是set属性名字(当在setter方法名字中,注意属性的名字的第一个字母是大写)。至关重要的是,当你创建自定义访问方法的时候,你要使用正确的名字;否则,默认访问方法将代替你自定义的方法。
To implement a custom setter for the master list property
为主列表属性实现自定义setter方法
Add the following code lines within the @implementation block of BirdSightingDataController.m:
在BirdSightingDataController.m的@implementation代码块中添加如下代码行。
- (void)setMasterBirdSightingList:(NSMutableArray *)newList {
if (_masterBirdSightingList != newList) {
_masterBirdSightingList = [newList mutableCopy];
}
}
By default, Xcode does not include a stub implementation of the init method when you create new Objective-C class files. This is because most objects don’t need to do anything other than call [super init]. In this tutorial, the data controller class needs to create the master list.
默认情况下,当你创建新的Objective-C 类文件的时候,Xcode不能包含init方法的根实现。这是因为大多数对象除了调用[super init]外不需要做任何事情。在本教程中,数据控制器类需要创建主列表。
To initialize the data controller object
初始化数据控制器对象
Enter the following code lines within the @implementation block of BirdSightingDataController.m:
在BirdSightingDataController.m的@implementation代码块中输入如下代码行。
- (id)init {
if (self = [super init]) {
[self initializeDefaultDataList];
return self;
}
return nil;
}
This method assigns to self the value returned from the super class’s initializer. If [super init] is successful, the method then calls the initializeDefaultDataList method that you wrote earlier and returns the newly initialized instance of itself.
这个方法分配从超类的初始化返回的值给自身。如果[super init] 成功,本方法将调用你之前写的initializeDefaultDataList方法,并且返回新的它自身的初始化实例。
You’ve given the data controller class the ability to create the master list, populate it with a placeholder item, and initialize a new instance of itself. Now give other objects the ability to interact with the master list by implementing the three data-access methods you declared in the header file:
你给数据控制器类能力来创建主列表、使用占位项填充它、并初始化新的它自身的对象。现在通过实现三个你在头文件中声明的数据访问方法给其他对象以与主列表交互的能力。
countOfList
objectInListAtIndex:
addBirdSightingWithSighting:sighting:
To implement the data controller’s data-access methods
实现数据控制器的数据访问方法
1.Implement the countOfList method by entering the following code lines in the @implementation block of BirdSightingDataController.m:
在BirdSightingDataController.m的@implementation代码块中通过输入如下代码行实现countOfList方法。
- (NSUInteger)countOfList {
return [self.masterBirdSightingList count];
}
The count method is an NSArray method that returns the total number of items in an array. Because masterBirdSightingList is of type NSMutableArray, which inherits from NSArray, the property can respond to the count message.
count 方法是NSArray方法,它返回数组中的项的总数。因为masterBirdSightingList是NSMutableArray类型,它继承自NSArray,属性能响应 count消息。
2.Implement the objectInListAtIndex: method by entering the following code lines:
通过输入下面的代码行来实现objectInListAtIndex:
- (BirdSighting *)objectInListAtIndex:(NSUInteger)theIndex {
return [self.masterBirdSightingList objectAtIndex:theIndex];
}
3.Implement the addBirdSightingWithSighting:sighting: method by entering the following code lines:
通过输入以下代码行实现addBirdSightingWithSighting:sighting:方法:
- (void)addBirdSightingWithSighting:(BirdSighting *)sighting {
[self.masterBirdSightingList addObject:sighting];
}
This method creates and initializes a new BirdSighting object by sending to the initWithName:location:date: method the name and location the user entered, along with today’s date. Then, the method adds the new BirdSighting object to the array.
这个方法通过发送用户输入的名字和地址、以及今天的日期给initWithName:location:date:方法来创建并初始化了一个新的BirdSighting对象。然后,该方法添加新的BirdSighting对象给数组。
When you finish entering the code in this step, you complete the implementation of BirdSightingDataController and Xcode removes the warning indicator.
当你完成输入本步骤的所有代码后,你完成了BirdSightingDataController的实现,并且Xcode也移除了警告指示。
You can build and run the app at this point, but nothing has changed from the first time you ran it because the view controllers don’t know anything about the data model you implemented. In the next chapter, you edit the master view controller and app delegate files so that the app can display the placeholder data.
你现在可以构建并运行app了,但是与你上次运行它的时候没什么改变,因为视图控制器不知道你实现的数据模型的任何事。在下一章中,你将编辑主视图控制器和app delegate 文件,这样app能显示占位数据。
Recap
回顾
In this chapter, you designed and implemented the data layer for the BirdWatching app. Following the MVC design pattern, you created classes that contain and manage the data that the app works with.
在本章中,你设计并实现了BirdWatching app 的数据层。根据MVC设计模式,你创建了包含和管理app使用的数据的类。
At this point in the tutorial, the project should contain interface and implementation files for both the BirdSighting and the BirdSightingDataController classes. The code for all four files is listed below so that you can check the code in your project for accuracy.
本教程到现在,工程应该包含BirdSighting和BirdSightingDataController的接口和实现文件。这四个文件的代码已经在下面列出,你可以与你项目进行对比以确定是否正确。
The code in BirdSighting.h should look like this:
BirdSighting.h的代码:
#import
@interface BirdSighting : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *location;
@property (nonatomic, strong) NSDate *date;
-(id)initWithName:(NSString *)name location:(NSString *)location date:(NSDate *)date;
@end
The code in BirdSighting.m should look like this:
BirdSighting.m的代码:
#import "BirdSighting.h"
@implementation BirdSighting
-(id)initWithName:(NSString *)name location:(NSString *)location date:(NSDate *)date
{
self = [super init];
if (self) {
_name = name;
_location = location;
_date = date;
return self;
}
return nil;
}
@end
The code in BirdSightingDataController.h should look like this:
#import
@class BirdSighting;
@interface BirdSightingDataController : NSObject
@property (nonatomic, copy) NSMutableArray *masterBirdSightingList;
- (NSUInteger)countOfList;
- (BirdSighting *)objectInListAtIndex:(NSUInteger)theIndex;
- (void)addBirdSightingWithSighting:(BirdSighting *)sighting;
@end
The code in BirdSightingDataController.m should look like this:
#import "BirdSightingDataController.h"
#import "BirdSighting.h"
@interface BirdSightingDataController ()
- (void)initializeDefaultDataList;
@end
@implementation BirdSightingDataController
- (void)initializeDefaultDataList {
NSMutableArray *sightingList = [[NSMutableArray alloc] init];
self.masterBirdSightingList = sightingList;
BirdSighting *sighting;
NSDate *today = [NSDate date];
sighting = [[BirdSighting alloc] initWithName:@"Pigeon" location:@"Everywhere" date:today];
[self addBirdSightingWithSighting:sighting];
}
- (void)setMasterBirdSightingList:(NSMutableArray *)newList {
if (_masterBirdSightingList != newList) {
_masterBirdSightingList = [newList mutableCopy];
}
}
- (id)init {
if (self = [super init]) {
[self initializeDefaultDataList];
return self;
}
return nil;
}
- (NSUInteger)countOfList {
return [self.masterBirdSightingList count];
}
- (BirdSighting *)objectInListAtIndex:(NSUInteger)theIndex {
return [self.masterBirdSightingList objectAtIndex:theIndex];
}
- (void)addBirdSightingWithSighting:(BirdSighting *)sighting {
[self.masterBirdSightingList addObject:sighting];
}
@end
Next
Previous