`
kanwoerzi
  • 浏览: 1635573 次
文章分类
社区版块
存档分类
最新评论

四 cocoa中Foundation框架的介绍

 
阅读更多

cocoa中Foundation框架的介绍

自己好久没更新博客了,不能说没有时间,还是自己太懒惰了。有空就想玩玩游戏,聊聊天,总觉得有的是时间改天在写,就这样一拖再拖都一个月了。自己实在不好意思再拖了,所以做学问贵在持之以恒,难点也在这里。所以那些能够坚持不懈,持之以恒的人我都佩服的五体投地,这种品质真的很难培养啊。不发牢骚了,言归正传。下面我就分3部分,来分享一下自己的学习心得。首先会介绍下Foundation框架的大致架构,然后就重点分析下NSObject的组成,最后讲下cocoa编程中方法调用的精髓:SELECTOR IMP。

Foundation框架的架构

cocoa程序编写主要用到2个框架Foundation和ApplicationKit。其中Foundation框架主要定义了一些基础类,供程序员来使用,而Application kit主要是一些用户界面设计的类。Foundation框架中的所有类都继承自NSObject这个对象,等下会讲到这个对象,这里就暂且知道有这样一个超类就行了。Foundation框架的主要目标有一下几点:

1) 为内存管理,对象的创建,消息的传递定义基本的对象。

2)用Unicode编码定义字符串类,以及方便的支持语言本地化

3)支持对象的持久保存和发布。

这几点都是apple官方文档上写的设计Foundation框架的目标。

下面就分析下Foundation类设计的大致策略,首先是建立对象和清理对象的策略,对象释放池NSAutorelasePool是一个重要的对象,用来自动回收对象,从而让程序员方便的进行内存管理。其次就是可变大小的对象(例如NSMutableString),这些对象可以对我们常用的容器类,例如数组,字典,集合,堆栈进行方便的扩展,而不必关系这些容器扩展的方法。第三点就是类簇,就是一个抽象类和一些具体类的组合,这样就组成了我们需要的各种对象和方法,方便以后的调用。最后一点就是通知NSNotificationCentor,其实这个特点用到了一个重要的设计模式,观察者模式。相信如果看过五人组写的设计模式这本书,你一定对这个方法深有体会,因为它是设计模式中一个重要的方法。NSNotificationCentor类就是在这个基础上设计的。

那么Foundation框架到底有那些类组成哪?我会在以后的博客里,挑选一些常用的类进行详细的分析。这里就大致说以下Foundation框架有那些类组成吧。Foundation类的根是NSObject和NSCoping协议组成的,这两个定义了类的基本属性和方法。继承自NSObject的类大致可以分为这样几类:基本的数据类型的类,如 NSNumber 、一些集合类如NSString NSArray、一些代表系统信息的类如NSDate、还有一些系统实体的类如NSTread NSTast等等。

NSObject介绍

假如没有面向对象的语言,那么结构化的程序设计语言如何模拟类哪?那自然就想到了结构体,其实objective c是在c语言的基础上发展的,同样NSObject也是用结构体来实现的。首先来看下一段结构体模拟类的代码吧。

typedef struct my_objc_class *MetaClass;

typedef struct my_objc_class *MyClass;
struct my_objc_class {
MetaClass class_pointer;
struct my_objc_class* super_class;
const char* name;
long version;
unsigned long info;
long instance_size;
struct objc_ivar_list* ivars;
struct objc_method_list* methods;
struct sarray * dtable;
struct my_objc_class* subclass_list;
struct my_objc_class* sibling_class;
struct objc_protocol_list *protocols;
void* gc_object_type;
};

//这里就是自己定义一个类了。

MyClass student;

估计你看完这个结构体,会惊奇的说原来这就是NSObject啊,其实这不是NSObject的原型,因为苹果公司一向不喜欢开源,她的代码我们怎么可能得到那。上面的结构体,是GCC中定义的开源代码,从网上都可以下到,这就是一个类是如何用结构体实现的。下面我们就来逐行分析下这个结构体吧,来揭示一下类的本质。

1)class_pointer 顾名思义就是这个结构体本身的一个指针,相信大部人都知道java和c++中的this关键字的用法吧,在c++中this指针就是这里的class_point。而objective c则是用的self来表示自身的指针的。

2)super_class 看到这里就知道继承是怎么回事了吧,就是在结构体里放上一个指针指向它的父节点。懂得了这点如果想要实现c++中的多重继承,无非就是用指针数组或者链表就可以了。

3)name version和info我要放到一块说了,因为她们都大同小异。name就是你定义的类的名字。任何产品都要有个版本吧,类同样也是人们设计出来的产品,version就是要给你的类加一个版本号,方便日后升级。info就是相当于一个ID,来区分你创建了多少个这样的结构体,也就是类。

4)instance_size 这就是类的关键部分,在类中叫成员变量,这个大小是如何分配的,是根据你在类中定义了多少实例。这样在这个类去初始化的时候,就会读取instance_size中的数据,在c语言中就用malloc给这个结构体分配大小。

5)ivars 表示的是类成员变量的列表,成员变量在分配好大小之后,ivars就存取了她们的地址,从而可以方便的访问到成员变量。所以说c++对类成员变量作用区域的限制,如pravite都是语法上的限制,如果你知道类是如何设计的,就可以先读取类的地址,接着让指针偏移一个变量的大小就可以访问到类中pravite的变量了。

6)methods 方法列表,和实例变量设计的类似,无非这个列表是个函数指针列表吧了,存的都是函数指针。这里就不赘余了。

7)dtable 这个要就是一些语言可以实现动态绑定的关键,在c++中这就是一个虚表,当这个虚表中有数据的时候,函数调用的时候就会首先在methods列表中找到方法的地址,然后从dtable查找符合这个方法应该有多少偏移量,从而访问到正确的地址。objective c中消息同样也是这样实现的。下面是objective c每次方法调用时都会调用lookup这个方法。

objc_msg_lookup(idreceiver,SELop)
{
if (receiver)
return sarray_get(receiver -> class_pointer -> dtable,(sidx)op);
else
return nil_method;

8)subclass_list 是子类的列表指针这里不再赘余。

9) sibling_class 是兄弟类的列表,类的结构明显看出来是数据结构中树的原型,用链表表示树的方法多种多样,这里用到的是孩子兄弟表示法。

10)protocols 这里特意用这个名字是为了方便说明objectivc的协议,如果用面向对象的统一定义解释的话,这个指针是用来实现接口的,在c++中叫纯虚对象。

11)gc_object_type 类方法和类变量从那而来的,这就是答案。

有了上面的基础下面介绍SELECTOR和IMP就容易多了。

SELECTOR和IMP

下面的内容主要以代码的形式演示下,在cocoa中类的方法调用是如何实现的。这里我定义了2个很简单的类纯属是用来模拟数据的。 athlete和footballPlayer。其中footballPlayer继承自athlete,代码如下:

//
// athlete.h
// SelectorAndFuntion
//
// Created by mengtnt on 10-12-8.
// Copyright 2010 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface athlete : NSObject
{
NSString *name;
}
- (void)show;
@end


#import "athlete.h"
@implementation athlete

- (id)init
{
self = [super init];
if (self)
{
name = [[NSString alloc] initWithString:@"Rossi"];
}
return self;
}


- (void)dealloc
{
[name release];
[super dealloc];
}


- (void)show
{
NSLog(@"My name is %@/n",name);
}

@end

//
// footballPlayer.h
// SelectorAndFuntion
//
// Created by mengtnt on 10-12-8.
// Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import <Cocoa/Cocoa.h>
#import "athlete.h"

@interface footballPlayer : athlete
{
NSNumber *goalNumber;
}
@end

#import "footballPlayer.h"


@implementation footballPlayer

- (id)init
{
self = [super init];
if (self)
{
goalNumber = [[NSNumber alloc] initWithUnsignedInt:100];
}
return self;
}


- (void)dealloc
{
[goalNumber release];
[super dealloc];
}


- (void)show
{
NSLog(@"Goal is %@/n",goalNumber);
}

@end

那么利用上面两个数据类,下面这个类就模拟了cocoa中消息的发送。

// doProx.h
// SelectorAndFuntion

// 这个类是用来演示Class,SEL,IMP,函数指针在objective c中如何使用。
// 1.SEL IMP 函数名字的关系。其中SEL是apple给每个函数分配的ID,IMP代表函数指针。关系图如下:
// footballPlayer 类
// 方法名字 方法ID(假设) 地址(假设)
// show 1001 0x2001

// 2.其中会用到获取函数ID的方法selector和通过函数ID调用函数的方法performSelector,等等这些函数的用法。
// 另外,反之我们可以用NSSelectorFromString方法来查找此函数名字的ID。

// 3.我们可以利用methodForSelector来获得函数的指针。并且还利用函数指针,来展示objective c中的performSelector是如何实现的。

// 4.同样我们可以通过一个普通的字符串取得这个Class类型(方法NSClassFromString),也可以通过我们生成的对象取得这个Class.
// Selector和Class比较类似,而Class类型获得的方法ClassName.不同的地方是Selector用于表示方法.


// Created by mengtnt on 10-12-8.
// Copyright 2010 __MyCompanyName__. All rights reserved.


#import <Cocoa/Cocoa.h>

#define SHOW @"show" //函数show的字符串。
#define FOOTBALLPLAYER_CLASS @"footballPlayer" //类footballPlayer的字符串

@interface doProx : NSObject
{
id athleteInstance[2]; //因为要动态的调用athlete中的show和footballPlayer的show方法,所以要定义为id类型。
SEL show_SEL;
IMP show_IMP;
void(*show_Func) (id, SEL); //函数指针是用来展示IMP在cocoa中是如何实现的。因为IMP其实定义就是函数指针。
Class footBallPlayerClass;
}
- (void)setSEL;

- (void)showResult;
@end

#import "doProx.h"
#import "athlete.h"
#import "footballPlayer.h" //在这里才包含两个头文件,这样才能体现程序动态执行的效果。

@implementation doProx
//分别给athlete赋予不同的对象
- (id)init
{
self = [super init];
//第一种获得类对象的方法,是用类方法调用获得此对象
athleteInstance[0] = [[athlete alloc] init];

//第二种获得类对象的方法,首先通过类的字符串获得类的类型,然后用此类型的类方法调用创建对象。
footBallPlayerClass = NSClassFromString(FOOTBALLPLAYER_CLASS);
athleteInstance[1] = [[footBallPlayerClass alloc] init];
return self;
}

- (void)dealloc
{
[athleteInstance[0] release];
[athleteInstance[1] release];
[super dealloc];
}

//如何获取SEL变量的值。SEL的值是根据函数名字获得的,相同的名字具有相同的ID。
- (void)setSEL
{
//方法一用函数名字获得。
//show_SEL = @selector(show);

//方法二用函数的字符串获得。
show_SEL = NSSelectorFromString(SHOW);
}

- (void)showResult
{
show_IMP = [athleteInstance[0] methodForSelector:show_SEL];
show_IMP(athleteInstance[0],show_SEL);

show_Func=(void (*)(id, SEL)) [athleteInstance[1] methodForSelector:show_SEL];
show_Func(athleteInstance[1],show_SEL);

//展现perform的用法,判断这个对象必须是footballPlayer类型才能执行。
for(int i = 0;i < 2;i++)
{
if ([[athleteInstance[i] className] isEqualToString:FOOTBALLPLAYER_CLASS])
{
[athleteInstance[i] performSelector:show_SEL];
}
}

NSString *myName = NSStringFromSelector(_cmd);
NSLog(@"Running in the method of %@", myName);
}
@end
然后在主函数里面调用这些方法。

#import <Foundation/Foundation.h>
#import "doProx.h"
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
doProx *proxy = [[doProx alloc] init];

[proxy setSEL];
[proxy showResult];
[pool drain];
return 0;
}

有兴趣的可以把代码复制过去调试下,在debuger中观察各个实例变量和方法的指针是如何变化的,相信有了这些基础以后学习Foundation框架中的常用类就不会有什么困难了。

分享到:
评论

相关推荐

    Cocoa框架ForiOS(一)框架的介绍

    Cocoa框架是iOS应用程序的基础,了解Cocoa框架,对开发iOS应用有很大的帮助。...iOS中,Cocoa众多框架中最重要最基本的两个框架是:Foundation和UIKit。Foundation和界面无关,也可以说和界面无关的类基本是

    GVCFoundation:Cocoa Foundation 框架静态库

    全球价值链基金会基础扩展和类别向詹金斯添加了 github 推送钩子 :)

    iOS技术概述

    iOS技术概述 介绍 4 谁应阅读本文档? 4 本文档的组织方式 5 获取iPhone SDK 5 提供反馈 5 其他参考资料 6 iOS 开发相关信息 6 iOS 架构 6 ...设备中的框架 46 模拟器的框架 49 系统库 49 文档修订历史 50

    Using Swift with Cocoa and Objective-C完整中文CocoaChina精校版

    在 Swift 中,你可以使用 Objective-C 的 API(包括系统框架和你自定义的代码),你也可以在 Objective-C中 使用 Swift 的 API。这种兼容性使 Swift 变成了一个简单、方便并且强大的工具集成到你的 Cocoa 应用开发...

    coresupport:Apple的Foundation和Cocoa框架的实用程序类和扩展

    核心支持 版本0.1-可以在获得源代码。 版权所有2010 Joachim Fornallaz。 版权所有。 介绍 核心支持是一组针对Apple的Foundation-和Cocoa框架的Objective-C实用程序类扩展。

    apple mac ios cocoa Class Hierarchy Chart(类继承图)

    apple的框架主要包括Foundation、 APPKit、 UIKit. appkit是mac平台用的, UIKit是ios平台用的。Foundation是两个平台上都可以用的。 本来想把我发布的的MFC QT的类图和cocoa的类图打包成一个压缩包的。 但前面两...

    MFC QT Cocoa 最新类继承图(Class Hierarchy Chart)汇总

    cocoa主要框架包括Foundation AppKit UIKIT, Appkit is for mac platform, UIKit is for iOS platform. 因为这里不准贴HTML标签。 需要官方网址的同学请在评论时留邮箱给我, 我会尽快回复。

    ios应用开发所有的实验.zip

    2:利用 Object C 和 Cocoa 框架,利用上次实验实现的表达式求值的类来开发一个四则运算器在模拟器中运行3:在上次实验实现的单场景计算器的基础上,利用导航控制器实现高级计算功能,完成所有的高级计算器

    swift开发文档中文版

    我们在 Foundation 和 Cocoa的基础上构建框架栈并将其标准化。Objective-C 本身支持块、集合语法和模块,所以框架可以轻松支持现代编程语言技术。正是得益于这些基础工作,我们现在才能发布这样一个用于未来苹果软件...

    swift中文教程

    我们在 Foundation 和 Cocoa 的 基础上构建框架栈使其完全现代化和标准化。 Objective-C 本身支持块、集合语法和模块,所以框架可以轻松支 持现代编程语言技术。正是得益于这些基础工作,我们现在才能发布这样一个...

    《Objective-C 2.0程序设计(原书第2版)》[PDF]

    第二部分详细阐述了foundation框架,涵盖数字、字符串、集合、文件操作、内存管理、对象复制和归档等重要内容;第三部分简要介绍了cocoa和iphone sdk;第四部分是附录,主要列出了objective-c的快速参考。. 本书结构...

    《Objective-C2.0程序设计(原书第2版)》_中文完整版

    第二部分详细阐述了Foundation框架,涵盖数字、字符串、集合、文件操作、内存管理、对象复制和归档等重要内容;第三部分简要介绍了Cocoa和iPhone SDK;第四部分是附录,主要列出了Objective-C的快速参考。 ...

    Objective-C 2.0程序设计

    部分详细阐述了Foundation框架,涵盖数字、字符串、集合、文件操作、内存管理、对象复制和归 档等重要内容;第三部分简要介绍了Cocoa和iPhone SDK;第四部分是附录,主要列出了Objective- C的快速参考。  本书结构...

    Programming in Objective-C, 4th Edition

    第二部分详细阐述了Foundation框架,涵盖数字、字符串、集合、文件操作、内存管理、对象复制和归档等重要内容;第三部分简要介绍了Cocoa和iPhone SDK;第四部分是附录,主要列出了Objective-C的快速参考。 ...

    Objective-C.2.0 程序设计

    一本很好的关于Object-C语言的书,介绍了Object-C,Foundation框架,CoCoa程序设计和IPhone SDK

    Swift中文教程 PDF

    我们在 Foundation 和 Cocoa 的基础上构建框架栈并将其标准 化。Objective-C 本身支持块、集合语法和模块,所以框架可以轻松支持现代编程语言技术。正是得益于这些基础工作,我们 现在才能发布这样一个用于未来苹果...

    swift最新中文文档

    我们在 Foundation 和 Cocoa的基础上构建框架栈并将其标准化。Objective-C 本身支持块、集合语法和模块,所以框架可以轻松支持现代编程语言技术。得益于这些基础工作,我们现在可以发布一个新语言,用于未来的苹果...

Global site tag (gtag.js) - Google Analytics