文档章节

Start Developing iOS Apps Today系列(十)

Lambda8421
 Lambda8421
发布于 2015/01/29 09:09
字数 2424
阅读 45
收藏 1

Start Developing iOS Apps Today系列之应用程序


十、编写自定类


      开发 iOS 应用程序时,很多情况下都需要编写自定类。当您需要将自定行为与数据打包在一起时,自定类非常有用。在自定类中,可以定义您自己的行为来储存、操控和显示数据。

      例如,iOS 的“时钟”应用程序中的“世界时钟”标签。比起标准表格视图单元格,此表格视图中的单元格需要显示更多内容。这是实现子类的绝好机会,可以扩展UITableViewCell的行为,从而在给定的表格视图单元格中显示更多自定数据。如果要设计此自定类,您可能要为标签添加 Outlet,使信息前显示小时数;还要添加图像视图,使单元格的右侧显示自定时钟。

image: ../Art/custom_class_2x.png

      本章会告诉您需要了解哪些 Objective-C 语法和类结构,才能实现 ToDoList 应用程序的行为。还讨论了XYZToDoItem的设计,该自定类将表示待办事项列表上的单个项目。在第三个教程中,您将真正实现该类,并将它添加到您的应用程序中。

声明并实现类

      在 Objective-C 中,类的说明需要两个不同的部分:接口和实现。接口准确指定了一个给定类型的对象,如何专用于其他对象。换句话说,它定义了类的实例与外部世界之间的公共接口。这个实现包括的可执行代码,涵盖了接口中声明的每个方法。

      对象的设计,应当隐藏其内部实现的细节。在 Objective-C 中,接口和实现通常放在单独的文件中,这样您只需要将接口设定为公共属性。和 C 代码一样,您需要定义头文件和源代码文件,将公共声明与代码的实现细节分开。接口文件具有.h扩展名,实现文件具有.m扩展名。(您将在“教程:添加数据”中为XYZToDoItem类真正创建这些文件;眼下我们只需跟着文稿来,因为所有内容都将讲到。)

接口

      Objective-C 语法经常采用以下方式来声明类接口:

  1. @interface XYZToDoItem : NSObject

  2. @end

      该示例声明了名为XYZToDoItem的类,它继承自NSObject。

      公共属性和行为在@interface声明内部定义。在此示例中,除了超类外,没有指定任何内容,所以XYZToDoItem实例唯一可用的行为继承自NSObject。所有对象都要有一个最基本的行为,因此在默认情况下,它们必须继承自NSObject(或它的一个子类)。

实现

      Objective-C 语法经常采用以下方式来声明类实现:

  1. #import "XYZToDoItem.h"

  2. @implementation XYZToDoItem

  3. @end

      如果您在类接口中声明了任何方法,那么需要在此文件中实现它们。

储存对象的数据的属性

      考虑待办事项需要保存的信息。您可能需要知道事项的名称,创建时间,以及是否已经完成。在自定XYZToDoItem类中,此信息储存在属性中。

      这些属性的声明在接口文件 (XYZToDoItem.h) 内部。如下所示:

  1. @interface XYZToDoItem : NSObject

  2. @property NSString *itemName;
  3. @property BOOL completed;
  4. @property NSDate *creationDate;

  5. @end

      在此示例中,XYZToDoItem类声明了三个公共属性。这些属性完全可供公开访问。在公开访问的情况下,其他对象可以同时读取和更改这些属性的值。

      您可能想要声明某个属性不能被更改(也就是说,只能读取)。指明一个属性是否只读(相对于其他属性),需要在 Objective-C 的属性声明中包括属性的特性。例如,如果您不想XYZToDoItem的创建日期被改变,可能需要将XYZToDoItem类接口更新为这样:

  1. @interface XYZToDoItem : NSObject

  2. @property NSString *itemName;
  3. @property BOOL completed;
  4. @property (readonly) NSDate *creationDate;

  5. @end

      属性可以是私有的或公共的。有时让属性私有是合理的选择,这样其他类就不能查看或访问它。例如,如果您想要跟踪的标记是项目完成的日期属性,并且不想让其他类访问此信息,请将此属性设为私有,方法是将它放在实现文件 (XYZToDoItem.m) 顶部的类扩展中。

  1. #import "XYZToDoItem.h"

  2. @interface XYZToDoItem ()
  3. @property NSDate *completionDate;
  4. @end

  5. @implementation XYZToDoItem

  6. @end

      您可以使用 getter 和 setter 来访问属性。getter 返回属性的值,setter 更改属性的值。访问 getter 和 setter 的常见语法简写是 dot notation(点表达式)。对于具有读写访问权限的属性,您可以使用点表达式来获取和设定属性的值。如果您有XYZToDoItem类的一个对象toDoItem,可以执行以下操作:

  1. toDoItem.itemName = @"Buy milk"; //Sets the value of itemName
  2. NSString *selectedItemName = toDoItem.itemName; //Gets the value of itemName

方法用来定义对象的行为

      方法用来定义对象能做些什么。方法是您定义的一段代码,用来执行类中的任务或子程序。它可以访问类中储存的数据,并使用该信息来执行一些操作。

      例如,要让待办事项 (XYZToDoItem) 能够被标记为已完成,您可以将markAsCompleted方法添加到类接口。稍后,您将在类实现中实现该方法的行为,正如“实现方法”中所述。

  1. @interface XYZToDoItem : NSObject

  2. @property NSString *itemName;
  3. @property BOOL completed;
  4. @property (readonly) NSDate *creationDate;
  5. - (void)markAsCompleted;

  6. @end

      方法名称前面的减号 (-) 指示它是一个实例方法,可以用该类的对象调用。减号将它与类方法区分开来,类方法用加号 (+) 来表示。类方法可通过类本身来调用。类方法的一个常见示例是类工厂方法,您已经在“处理 Foundation”中学习过。您也可以使用类方法来访问与类相关的一些共享信息。

      在声明的开始,用圆括号括住void关键词,表示方法不会返回值。这种情况下,markAsCompleted方法没有任何参数。“方法参数”中会讲述有关参数的更多信息。

方法参数

    在声明方法时加上参数,可在调用方法时传递一些信息。

    例如,您可以根据之前的代码片段修改markAsCompleted方法,让其带单个参数,借此确定项目是否标记为完成或未完成。用这种方式,您可以切换项目的完成状态,而不只是将它设为完成。

  1. @interface XYZToDoItem : NSObject

  2. @property NSString *itemName;
  3. @property BOOL completed;
  4. @property (readonly) NSDate *creationDate;
  5. - (void)markAsCompleted:(BOOL)isComplete;

  6. @end

    现在,您的方法采用了一个参数isComplete,其类型为BOOL。

    通过名称引用带一个参数的方法时,冒号将作为方法名称的一部分,所以更新后的方法名称是markAsCompleted:。如果方法有多个参数,那么它会被分解,并插入参数名称。如果要将另一个参数添加到此方法,其声明将会是这样的:

  1. - (void)markAsCompleted:(BOOL)isComplete onDate:(NSDate *)date;

在这里,方法的名称写为markAsCompleted:onDate:。实现时会使用名称isComplete和date(会将这些名称当作变量),来访问方法被调用时所提供的值。

实现方法

    方法实现使用大括号来包括相关代码。方法的名称必须与接口文件中的对应方法相同,并且参数和返回类型必须完全匹配。

    这是添加到XYZToDoItem类接口的markAsCompleted:方法的简单实现:

  1. @implementation XYZToDoItem
  2. - (void)markAsCompleted:(BOOL)isComplete {
  3.     self.completed = isComplete;
  4. }
  5. @end

    与属性一样,方法也可以是私有的或公共的。公共方法在公共接口中声明,因此可以被其他对象查看和调用。它们的相应实现存在于实现文件中,其他对象看不到。 私有方法仅有一个实现,并与类相同,这意味着只可以在类实现中调用它们。这是一个强大的机制,可将内部行为添加到类而不允许其他对象进行访问。

    例如,假设您想要让待办事项的completionDate保持更新。当待办事项被标记为完成,就将completionDate设定为当前日期。当它被标记为未完成,就将completionDate设定为nil,因为它尚未完成。由于更新待办事项的completionDate是自包含任务,所以最好的做法是为其编写专属方法。但是,应当确定其他对象不能调用此方法。否则,其他对象可以随时将待办事项的completionDate设定为任何内容。因此,请将此方法设为私有。

      现在,更新XYZToDoItem的实现来包括私有方法setCompletionDate,该方法将会在markAsCompleted:内部调用,以便在待办事项被标记为已完成或未完成时,更新待办事项的completionDate。请注意,您不会添加任何内容到接口文件,因为不想其他对象看到此方法。


  1. @implementation XYZToDoItem
  2. - (void)markAsCompleted:(BOOL)isComplete {
  3.     self.completed = isComplete;
  4.     [self setCompletionDate];
  5. }
  6. - (void)setCompletionDate {
  7.     if (self.completed) {
  8.         self.completionDate = [NSDate date];
  9.     } else {
  10.         self.completionDate = nil;
  11.     }
  12. }
  13. @end




      现在,您已经使用XYZToDoItem类定义了待办事项列表的基本实现。XYZToDoItem以属性的形式储存自身相关的信息——名称、创建日期和完成状态,并且会使用方法定义行为——被标记为已完成或未完成。这是您在下一个教程中实现 ToDoList 应用程序所需的功能扩展。不过,您随时可以尝试将自己的属性和方法添加到类,将新的行为集成到您的应用程序中。

© 著作权归作者所有

Lambda8421
粉丝 10
博文 121
码字总数 121640
作品 0
闸北
程序员
私信 提问
斯坦福大学的 Swift 教程又来了:还是免费的

美国斯坦福大学(Stanford University)曾在去年 4 月份推出过 iOS 编程教学课程 Developing iOS 9 Apps with Swift,这项课程上架 iTunes U 之后广受编程爱好者的好评。因为它不仅内容齐全,...

局长
2017/02/20
3.2K
11
iOS 学习资料整理

视频教程(英文) Developing iOS 7 Apps for iPhone and iPad 斯坦福开放教程之一, 课程主要讲解了一些 iOS 开发工具和 API 以及 iOS SDK 的使用, 属于 iOS 基础视频 iPad and iPhone Applic...

拉偶有所依
2015/01/19
2.5K
5
Start Developing iOS Apps Today系列(二)

Start Developing iOS Apps Today系列之入门 二、教程:基础 本教程描述了什么是应用程序、创建简单用户界面的过程,以及如何添加自定行为,将界面转变成可运行的应用程序。 遵循本教程,可了...

Lambda8421
2015/01/28
620
0
Is it too late to learn to code?

Erin Parker, Founder Spitfire Athlete, iOS Engineer 9k upvotes by Francis Chen, Gaurav Baheti, Yue-Wing Yau, Maria Guryanova,(more) It's never too late. So much can happen in a ......

明天以后
2015/07/16
174
0
Ionic系列——调用系统电话

1、需求描述 在ionic项目用调用手机的打电话功能。开始还想找cordova和ng-cordova的插件那,现在H5实现起来特别方便。 2、准备 在cordova中所有的URL Schemes 都是服从于白名单的,所以要现在...

龙马行空
2015/08/14
4.9K
0

没有更多内容

加载失败,请刷新页面

加载更多

PHP计算两个经纬度地点之间的距离

/** * 求两个已知经纬度之间的距离,单位为米 * * @param lng1 $ ,lng2 经度 * @param lat1 $ ,lat2 纬度 * @return float 距离,单位米 * @author www.Alixixi.com */function get...

子枫Eric
23分钟前
14
0
Linux—day 4

ch2 需要掌握的命令 (1)cat -n 1.txt (2)more 1.txt (3)head -n 15 initial-setup-ks.cfg (4)tail -n 17 initial-setup-ks.cfg;tail -f initial-setup-ks.cfg (5)cat -n anaconda-ks.c......

呵呵暖茶
35分钟前
16
0
【Kubernetes社区之路】我的PR被抢了

2019年11月的某天,我无意间发现一个PR作者在自己的PR中抱怨自己的PR没被合入,而另一个比自己提交晚且内容几乎一样的PR则被合入了。 字里行间透露些许伤感外加无奈: 作为一名开源爱好者,我...

恋恋美食
42分钟前
21
0
阻塞队列

对于许多线程问题, 可以通过使用一个或多个队列以优雅且安全的方式将其形式化。生产者线程向队列插人元素, 消费者线程则取出它们。 使用队列, 可以安全地从一个线程向另 一个线程传递数据...

ytuan996
43分钟前
23
0
mysql docker 配置

安装   主机上的mysql服务是基于docker安装的,具体安装脚本如下: docker run --detach \--restart always \--publish 3306:3306 --name mysql \--volume /data/mysql/logs:/logs \-...

qwfys
47分钟前
18
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部