zoukankan      html  css  js  c++  java
  • 学iOS开发(二)——实现一款App之编写自定义类

    今天学iOS开发(二)——实现一款App之编写自定义类                                            

     当开发iOS应用程序时,你会发现在许多场景下,你需要编写自己的自定义类。当你需要数据和自定义行为一起打包时,自定义类就很有用了。在一个自定义的类中,你可以为存储、操纵和显示数据定义你自己的行为。
     
           例如,考虑iOS Clock app中的全球时钟标签(World Clock tab)。这个表视图中的单元格需要显示比标准表视图单元格更多的内容。这是一个不错的机会实现一个扩展UITableViewCell行为的子类,从而在给定的表视图单元格中显示额外的自定义数据。如果你在设计这个自定义类,您可以为标签添加Outlets来显示时差信息,而单元格的右边用image view显示自定义时钟。
     
            本章将教你关于Objective-C语法和类结构的必要知识,从而实现你的ToDoList应用程序的行为。它讨论了XYZToDoItem的设计,这个自定义类代表to-do list上的单个项目。在第三个教程中,你将真正地实现这个类,并把它添加到应用程序中。
     
    类的声明与实现
     
            规范的Objective-C类由两部分组成:接口(interface)与实现(implementation)。接口准确地指定了一个给定的对象类型如何被其他对象使用。换句话说,它定义了类实例和外界之间的公共接口。该实现包括接口中声明的每个方法的可执行代码。
     
             一个对象的设计应该隐藏其内部的实现细节。在Objective-C中,接口和实现通常放置在单独的文件里,这样你需要做的就只是公共接口了。与C代码类似,定义头文件和源文件,从而把公开声明从代码的实现细节中分离出来。接口文件具有.h扩展名,实现文件具有.m的扩展名。(在Tutorial: Add Data中,你要实际为XYZToDoItem类创建这些文件。现在,只要跟着介绍的步骤来就行了。)
     
    接口(Interface)
    用于声明一个类接口的Objective-C语法如下:
    1. @interface XYZToDoItem : NSObject 
    2.   
    3. @end 
    这个例子声明了一个名为XYZToDoItem类,它继承自NSObject。
     
            公共属性和行为在@interface声明中定义。在这个例子里,没有任何指定超出父类,所以可以想到XYZToDoItem实例唯一可用的行为是从NSObject继承而来。所有对象有望有一个最低的行为,因此默认情况下,他们必须继承自NSObject(或它的子类)。
     
    实现(Implemenation)
          用于声明一个类实现的Objective-C语法如下:
    1. #import "XYZToDoItem.h" 
    2.   
    3. @implementation XYZToDoItem 
    4.   
    5. @end 
         如果在类接口中声明任何方法,你需要在这个文件中去实现它们。
     
    用属性存储对象的数据
     
           考虑一下待办事项需要持有什么样的信息。你可能需要知道它的名称,创建时间,以及是否已经完成。在你的自定义XYZToDoItem类中,你将会用properties来存储这些信息。
     
    在所在的接口文件(XYZToDoItem.h)内声明这些属性。如下面所示:
    1. @interface XYZToDoItem : NSObject 
    2.   
    3. @property NSString *itemName; 
    4. @property BOOL completed; 
    5. @property NSDate *creationDate; 
    6.   
    7. @end 
             在这例子当中,XYZToDoItem类声明了三个公共属性。这些属性公众可以全面访问。有了公共访问权限,其他对象就可以读取和改变其属性的值。
     
            你可能会决定声明一个不能被改变的属性(即它应该是只读的)。当指示一个属性打算设定为只读时,只需要Objective-C的属性声明中包含属性参数。举例来说,如果你不想要一个XYZToDoItem的创建的日期是不可变的,你只需更新XYZToDoItem类接口看起来像这样:
    1. @interface XYZToDoItem : NSObject 
    2.   
    3. @property NSString *itemName; 
    4. @property BOOL completed; 
    5. @property (readonly) NSDate *creationDate; 
    6.   
    7. @end 
             属性可以公有或私有。有时私有属性还是有意义的,这样其他类就不能查看或访问到它。举个例子,如果你想跟踪一个代表项目被标记为完成的日期的属性,而不给其他类访问这些信息的权限,只需在实现文件的顶部(XYZToDoItem.m)扩展你的私有类。
    1. #import "XYZToDoItem.h" 
    2.   
    3. @interface XYZToDoItem () 
    4. @property NSDate *completionDate; 
    5. @end 
    6.   
    7. @implementation XYZToDoItem 
    8.   
    9. @end 
            您可以使用getter和setter访问属性。getter返回一个属性值, setter改变一个属性值。一个常见的语法速记访问getter和setter方法是使用点符号。对于属性的读取和写入访问,您可以使用点符号获取和设置属性的值。如果你有类XYZToDoItem的一个对象TodoItem,您可以执行以下操作:
     
    1. toDoItem.itemName = @"Buy milk";                 //Sets the value of itemName 
    2. NSString *selectedItemName = toDoItem.itemName;  //Gets the value of itemName 
     
    用方法定义对象的行为 
           方法定义了一个对象的行为。方法是用来定义在一个类中执行任务或子程序的一段代码。方法可以访问存储在类中的数据,并且可以使用该信息来执行某种操作。
     
           例如,为让一个待办事项(XYZToDoItem)有能力被标记为已完成,你可以在类的接口中添加一个markAsCompleted方法。稍后,你将在类实现中实现此方法的行为,即Implementing Methods中的描述。
    @interface XYZToDoItem : NSObject 
    1. @interface XYZToDoItem : NSObject 
    2.   
    3. @property NSString *itemName; 
    4. @property BOOL completed; 
    5. @property (readonly) NSDate *creationDate; 
    6. - (void)markAsCompleted; 
    7.   
    8. @end 
            在方法名的前面加上减号(-)表明它是一个实例方法,它可以被该类的一个对象调用。减号的实例方法是为了与用加号(+)表示的类的方法区分开来。类方法可以被类本身调用。类方法的一个常见例子是类的工厂方法,你可以在Working with Foundation(中文)一节中了解它。您还可以使用类的方法来访问一些与类共享关联的信息片段。
     
           用于在声明开头的括号里的void关键字,表明该方法没有返回值。在这个例子中,markAsCompleted方法不接受参数。你可以在“ Method Parameters”中查看对参数的讨论。
     
    方法参数
            有参数的方法声明可以在你调用一个方法时传递一些必要信息。
     
            举例来说,你可以从上面的代码片段修改markAsCompleted方法使之拥有一个单一的参数,它将决定该项目是否被标记为完成或者未完成。通过这种方式,你可以完成状态的项目,而不是将它设置为只完成了该项目的状态。
    1. @interface XYZToDoItem : NSObject 
    2.   
    3. @property NSString *itemName; 
    4. @property BOOL completed; 
    5. @property (readonly) NSDate *creationDate; 
    6. - (void)markAsCompleted:(BOOL)isComplete; 
    7.   
    8. @end 
          现在,你声明的方法中有了一个BOOL类型的参数:isComplete。
     
           当你引用一个方法参数的名字时,冒号将作为方法名称的一部分,所以更新之后的方法名称现为markAsCompleted:。如果一个方法有多个参数,方法名称被分解并穿插着参数名。如果你想另添加一个参数到这个方法,它的声明是这样的:
    1. - (void)markAsCompleted:(BOOL)isComplete onDate:(NSDate *)date; 
    这里,所述方法的名称就应该写为markAsCompleted:onDate:。implementation中使用的isComplete和date被用来访问调用方法时提供的值,这些名字仿佛是变量。 
     
    实现方法
          方法实现使用大括号来包含相关的代码。该方法的名称必须与它在接口文件中相对应,参数和返回类型也必须完全匹配。下面是你添加到XYZToDoItem类接口中markAsCompleted:方法一个简单实现:
    @implementation XYZToDoItem 
    1. @implementation XYZToDoItem 
    2. - (void)markAsCompleted:(BOOL)isComplete { 
    3.     self.completed = isComplete; 
    4. @end 
            跟属性一样,方法也可以是公有或私有。公共方法在公共接口中声明,所以可以看到,并可以通过其他对象调用。其相应的实现只体现在实现文件中,对其他对象而言并不可见。私有方法只有一个实现,是类的内部方法,这意味着他们只在类实现的内部调用。这是一个向类添加内部行为的强有力的机制,而不允许其他对象访问它。
     
             例如,假设你要保留一个待办事项的completionDate更新。如果待办事项被标记为已完成,设置completionDate为当前日期。如果它被标记为未完成,completionDate设置为nil,因为它尚未完成。因为更新待办项目的completionDate是一个自包含的任务,最佳实践是编写自己的方法。然而,值得注意的是你要确保其他对象不能调用该方法,否则,其他对象可以在任何时间把to-do项目的completionDate设置为任何值。出于这个考虑,你可以把函数设为私有。
     
             现在,更新XYZToDoItem的实现,以包含在 markAsCompleted:内调用的私有方法setCompletionDate ,来更新to-do项目的completionDate,无论何时当它被标记为完成或者未完成。注意,你没有在口文件中添加任何代码,因为你不想其他对象看到这个方法。
    1. @implementation XYZToDoItem 
    2. - (void)markAsCompleted:(BOOL)isComplete { 
    3.     self.completed = isComplete; 
    4.     [self setCompletionDate]; 
    5. - (void)setCompletionDate { 
    6.     if (self.completed) { 
    7.         self.completionDate = [NSDate date]; 
    8.     } else { 
    9.         self.completionDate = nil; 
    10.     } 
    11. @end 
             此时,你已经使用了XYZToDoItem类定义了to-do列表项的基本表示。XYZToDoItem以属性的形式存储了与自身有关的信息,比如名称,创建日期,完成状态等,并且它定义了它能做什么—标记为已完成或未完成—使用一个方法。在接下来的教程中,你需要在你的ToDoList app中实现这些特性。但是,您可以尝试为类添加自己的属性和方法,从而把新的行为整合到你的app中
  • 相关阅读:
    cinder支持nfs快照
    浏览器输入URL到返回页面的全过程
    按需制作最小的本地yum源
    创建可执行bin安装文件
    RPCVersionCapError: Requested message version, 4.17 is incompatible. It needs to be equal in major version and less than or equal in minor version as the specified version cap 4.11.
    惠普IPMI登陆不上
    Linux进程状态——top,ps中看到进程状态D,S,Z的含义
    openstack-neutron基本的网络类型以及分析
    openstack octavia的实现与分析(二)原理,架构与基本流程
    flask上下文流程图
  • 原文地址:https://www.cnblogs.com/ios1/p/3739097.html
Copyright © 2011-2022 走看看