[学习笔记—Objective-C]《Objective-C-基础教程 第2版》第十二章 类别

12.1 创建类别

类别(category)是一种为现有的类添加新方法的方式

例:获取字符串的长度并存入NSDictionary字典中

  • 不使用类别的方式:
      NSNumber *number;
      number = [NSNumber numberWithUnsignedInt: [string length]];
      // ... do something with number
  • 使用类别的方式:

    • 类别的声明:
@interface NSString (NumberConvenience)

- (NSNumber *) lengthAsNumber; 

@end // NumberConvenience

注意

  1. 括号内写入类别的名称,添加给NSString的
  2. 类别不能添加实例变量,所以没有实例变量的声明部分
  3. 可以添加属性,但属性必须是dynamic类型的,添加属性的好处是可以通过点表达式访问setter和getter方法
    • 类别的实现:
- (NSNumber *) lengthAsNumber{

    unsigned int length = [self length];
    return ([NSNumber numberWithUnsignedInt: length]);

    //向字符串发送lengthAsNumber,返回该字符串的长度的NSNumber对象

} // lengthAsNumber

测试文件:


    NSMutableDictionary *dict;
    dict = [NSMutableDictionary dictionary];

    [dict setObject: [@"hello" lengthAsNumber]
             forKey: @"hello"]; 

    [dict setObject: [@"iLikeFish" lengthAsNumber]
             forKey: @"iLikeFish"];

    [dict setObject: [@"Once upon a time" lengthAsNumber]
             forKey: @"Once upon a time"];

    NSLog (@"%@", dict); //输出:“键=键内容”

优点:只要输入一个字符串,向该字符串发送lengthAsNumber,立即能返回该字符串的长度的NSNumber对象

注意

此类别属于NSString,因此任何NSString对象都能响应lengthAsNumber消息

12.11 类别的缺陷:

  1. 无法向类中添加新的实例变量
  2. 名称冲突,类别的方法名与现有的方法重名时,类别具有更高的优先级(利用前缀避免)

12.12 类别的优势:

  1. 将类的实现代码分散到多个不同文件或框架中
  2. 创建对私有方法对向前引用
  3. 向对象添加非正式协议(informal protocol)

12.2 类扩展(class extension)

类扩展:一种特殊的类别,不需要名字。

特点:

  1. 不需要名字
  2. 可以在你自己的类中使用它
  3. 可以添加实例变量
  4. 可以将只读权限改成可读写的权限
  5. 创建数量不限

例:建立Things类的扩展

  • 原Things类:
@interface Things : NSObject

@property (assign) NSInteger thing1;
@property (readonly, assign) NSInteger thign2;
  • 扩展Things类:

//获取Things类,并通过添加私有属性和方法扩展它
@interface Things()
{
  NSInteger thing4;//私有的
}

@property (readwrite, assign) NSInteger thing2;//改变了读写权限,只能在这个类中访问的私有方法,在公共的接口只有getter方法
@property (assign) NSInteger thign3;//私有的

注意:

面向对象编程的一个特征就是信息隐藏,只需要把用户需要的展示出来,其他的不需要。我们可以把这个类别放在.m文件中,也可以放在私有的头文件中。

12.3 利用类别分散实现代码

如果想将大型(有很多方法)的类分散到多个不同的.m文件中,可以使用类别。

NSWindow类有数百个方法,但使用分类:

@interface NSWindow(NSKeyboardUI) //键盘
@interface NSWindow(NSToolbarSupport) //工具栏
@interface NSWindow(NSDrag) //拖放功能
@interface NSWindow(NSCarbonExtensions)

注意:

  1. 类别可以访问其继承的类的实例变量
  2. 不仅可以将一个类的实现代码分散到多个不同的源文件中,还可以分散多个不同的框架中

Cocoa的设计人员通过类别使数据功能放在Foundation框架中,而绘图共呢个放在Appkit框架中。

12.4 通过类别创建向前引用(Forward References)

如果在不方便将方法声明的前提下调用方法,或者正在使用的是另一个类中尚未发布的方法,那么就需要类别。

具体做法:

Car类的公共接口里声明rotateTires的方法,在类别中声明move

TireFromPosition:toPosition:的方法来实现rotateTires的方法,rotateTires方法可以使用它。

@intreface Car(Private)

-(void)moveTireFromPosition:(int) pos1 toPosition: (int) pos2;

@end // Private

注意:放入各自的@implementation文件中

12.5 非正式协议和委托类别

非正式协议是NSObject的一个类别,列出了对象可以响应的方法。非正式协议用于实现委托

委托(delegate)是一种对象,由另一个类请求执行某些工作。委托是一种允许你轻松定制对下岗行为的技术。

例:

当用户点击某行时,tableView对象准备执行之前,它会询问其委托对象是否能选择此行。

12.51 ITUnesFinder 项目 (略)

  //新的NSNetServiceBrowser对象:
  NSNetServiceBrowser *browser;
  browser = [[NSNetServiceBrowser alloc] init];

  //新的ITunesFinder对象
  ITunesFinder *finder;
  finder = [[ITunesFinder alloc] init];

  //告诉 net browser将 ITunesFinder 对象作为代理
  [browser setDelegate: finder];

  //告诉浏览器搜索iTunes共享
  [browser searchForServicesOfType: @"_daap._tcp"
           inDomain: @"local."];

12.52 委托和类别

委托是类别的另一种应用,一个NSObject的类别可以被发送给委托对象

@interface NSObject (NSNetServiceBrowserDelegateMethods)
- (void) netServiceBrowserWillSearch:
       (NSNetServiceBrowser *) browser;

- (void) netServiceBrowserDidStopSearch:
      (NSNetServiceBrowser *) browser;

- (void) netServiceBrowser:
      (NSNetServiceBrowser *) browser
     didRemoveService: (NSNetService *) service
     moreComing: (BOOL) moreComing;
@end

通过声明为NSObject的类别,NSNetServiceBrowser可以给任何对象(作为代理的对象)发送其中一条消息-为非正式协议

注意:对于非正式协议,你只声明你想声明的即可。

12.53 响应选择器

选择器(selector):只是一个方法名称

指定选择器:@selector();

Car类的setEngine:方法的选择器:@selector(setEngine:)

Car类的setTire:atIndex:方法的选器:@selector(setTire:atIndex:)

询问对象其是否能响应某个特定的消息

Car *car = [[Car alloc] init];
if([Car respondsToSelector: @selector(setEngine:)])
{
    NSLog(@"Yes");

}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-10 06:28:23

[学习笔记—Objective-C]《Objective-C-基础教程 第2版》第十二章 类别的相关文章

PHP 学习笔记(一):基础教程:语法,变量,函数,数组,超全局

PHP简介 PHP 脚本在服务器上执行. 什么是 PHP 文件 PHP 文件能够包含文本.HTML.CSS 以及 PHP 代码 PHP 代码在服务器上执行,而结果以纯文本返回浏览器 PHP 文件的后缀是 ".php" PHP能够做什么 PHP 能够生成动态页面内容 PHP 能够创建.打开.读取.写入.删除以及关闭服务器上的文件 PHP 能够接收表单数据 PHP 能够发送并取回 cookies PHP 能够添加.删除.修改数据库中的数据 PHP 能够限制用户访问网站中的某些页面 PHP

python基础学习笔记——Python基础教程(第2版 修订版)第12章(图形用户界面)

#丰富的平台 Tkinter wxpython ..... #wxpython import wx app=wx.App() win=wx/Frame(None) win.Show() app.MainLoop() #增加按钮a app=wx.App() win=wx.Frame(None) btn=wx.Button(win) win.Show() app.MainLoop() win=wx.Frame(None,title="simple Editor") loadButton=w

python基础学习笔记——Python基础教程(第2版 修订版)第三章(字符串)

#字符串 '%s plus %s equals %s'%(1,2,3) %10f %pi %10.2f %5s %'guido van poee %.*s %(5,'gjffuygv')%010.2 0000003.14%-10.2f #字符串方法 string.letters 包含所有字母的字符串 #find    title.find("sdf")  没有返回-1 #join  添加元素 #lower #replace("isj,"ss") #'1+2

python基础学习笔记——Python基础教程(第2版 修订版)第四章(字典)

#创建 phone={'alice':'12234','beth':'352235'} #dict使用 items=[('name','gumby'),('age',42)} d=dict(items) d=dict(name='gumby',age=42) #基本字典操作 lend(d) d[k] d[k]=v k in d x={} x[42]='foobae' x {42:'foobar'} people={'alice':{'phone':'123','addr':'foo drive3

python基础学习笔记——Python基础教程(第2版 修订版)第11章(文件与素材)

#文件模式 open(name[.mode[.buffering]]) r w a b + f=open(r'c:\text\somefile') #基本文件方法 #对文件内容进行迭代 f=open('somefile.txt','w') #r是默认的 f.write('hello') f.read(4) f.close() #管式输出 $ cat somefile.txt|python somescript.py|sort #读写行 writelines readlines #关闭文件 #对文

《Python基础教程 第2版·修订版》 第2章 列表和元组(学习笔记·总)

这章东西有点多,因此,分成了三份来写,总体来说,这章内容较基础,以下是一二三的链接 <Python基础教程 第2版·修订版>第2章 列表和元组(学习笔记·一) <Python基础教程 第2版·修订版>第2章 列表和元组(学习笔记·二) <Python基础教程 第2版·修订版>第2章 列表和原组 (学习笔记·三) 版权声明:本文为博主原创文章,未经博主允许不得转载.

《python基础教程(第二版)》学习笔记 字符串(第3章)

<python基础教程(第二版)>学习笔记 字符串(第3章)所有的基本的序列操作(索引,分片,乘法,判断成员资格,求长度,求最大最小值)对字符串也适用.字符串是不可以改变的:%左侧是格式字符串,右侧是需要格式化的值print '%s=%d' % ('x',100) ==> x=100%% 格式字符串中出现 %模板字符串:from string import Templates=Template('$x is 100');  s.substitute(x='ABC');  ==> '

《Python基础教程(第二版)》学习笔记 -&gt; 第九章 魔法方法、属性和迭代器

准备工作 >>> class NewStyle(object): more_code_here >>> class OldStyle: more_code_here 在这两个类中,NewStyle是新式的类,OldStyle是旧式的类,如果文件以__metaclass__ = type 开始,那么两个类都是新式类. 构造方法 构造方法,当一个对象被创建后,会立即调用构造方法.Python中创建一个构造方法,只要把init方法的名字从简单的init修改成__init__

《Python基础教程(第二版)》学习笔记 -&gt; 第十章 充电时刻 之 标准库

SYS sys这个模块让你能够访问与Python解释器联系紧密的变量和函数,下面是一些sys模块中重要的函数和变量: 函数和变量 描述 argv 命令行参数,包括脚本和名称 exit([arg])                退出当前的程序,可选参数为给定的返回值或者错误信息 modules 映射模块名字到载入模块的字典 path 查找模块所在目录的目录名列表 platform 平台标识符 stdin 标准输入流-- 一个类文件对象 stdout 标准输出流-- 一个类文件对象 stderr