深入Objective-C的动态特性

Objective-C具有相当多的动态特性,基本的,也是经常被提到和用到的有动态类型(Dynamic typing),动态绑定(Dynamic binding)和动态加载(Dynamic loading)。

这些动态特性都是在Cocoa程序开发时非常常用的语言特性,而在这之后,OC在底层也提供了相当丰富的运行时的特性,比如枚举类属性方法、获取方法实现等等。虽然在平常的Cocoa开发中这些较底层的运行特性基本用不着,但是在某些情况下如果你知道这些特性并合理加以运用的话,往往能事半功倍~

动态特性基础

1、动态类型

即运行时再决定对象的类型。这类动态特性在日常应用中非常常见,简单说就是id类型。id类型即通用的对象类,任何对象都可以被id指针所指,而在实际使用中,往往使用introspection来确定该对象的实际所属类:

id obj = someInstance;
if ([obj isKindOfClass:someClass])
{
    someClass *classSpecifiedInstance = (someClass *)obj;
    // Do Something to classSpecifiedInstance which now is an instance of someClass
    //...
}

-isMemberOfClass: 是 NSObject 的方法,用以确定某个 NSObject 对象是否是某个类的成员。与之相似的为 -isKindOfClass:,可以用以确定某个对象是否是某个类或其子类的成员。这两个方法为典型的introspection方法。在确定对象为某类成员后,可以安全地进行强制转换,继续之后的工作。

2、动态绑定

基于动态类型,在某个实例对象被确定后,其类型便被确定了。该对象对应的属性和响应的消息也被完全确定,这就是动态绑定。在继续之前,需要明确Objective-C中消息的概念。由于OC的动态特性,在OC中其实很少提及“函数”的概念,传统的函数一般在编译时就已经把参数信息和函数实现打包到编译后的源码中了,而在OC中最常使用的是消息机制。调用一个实例的方法,所做的是向该实例的指针发送消息,实例在收到消息后,从自身的实现中寻找响应这条消息的方法。

动态绑定所做的,即是在实例所属类确定后,将某些属性和相应的方法绑定到实例上。这里所指的属性和方法当然包括了原来没有在类中实现的,而是在运行时才需要的新加入的实现。在Cocoa层,我们一般向一个NSObject对象发送-respondsToSelector:或者-instancesRespondToSelector:等来确定对象是否可以对某个SEL做出响应,而在OC消息转发机制被触发之前,对应的类的+resolveClassMethod:和+resolveInstanceMethod:将会被调用,在此时有机会动态地向类或者实例添加新的方法,也即类的实现是可以动态绑定的。一个例子:

void dynamicMethodIMP(id self, SEL _cmd)
{
    // implementation ....
}

//该方法在OC消息转发生效前被调用
+ (BOOL) resolveInstanceMethod:(SEL)aSEL
{
    if (aSEL == @selector(resolveThisMethodDynamically)) {
        //向[self class]中新加入返回为void的实现,SEL名字为aSEL,实现的具体内容为dynamicMethodIMP class_addMethod([self class], aSEL, (IMP) dynamicMethodIMP, “v@:”);
        return YES;
    }
    return [super resolveInstanceMethod:aSel];
}

当然也可以在任意需要的地方调用class_addMethod或者method_setImplementation(前者添加实现,后者替换实现),来完成动态绑定的需求。

3、动态加载

根据需求加载所需要的资源,这点很容易理解,对于iOS开发来说,基本就是根据不同的机型做适配。最经典的例子就是在Retina设备上加载@2x的图片,而在老一些的普通屏设备上加载原图。随着Retina iPad的推出,和之后可能的Retina Mac的出现,这个特性相信会被越来越多地使用。

iOS 深入Objective-C的动态特性的更多相关文章

  1. iOS 动态特性和RunTime

    过去的几年中涌现了大量的Objective-C开发者.有些是从动态语言转过来的,比如Ruby或Python,有些是从强类型语言转过来的,如Java或C#,当然也有直接以Objective-C作为入门语 ...

  2. ios Objective-C的动态特性

    这是一篇译文,原文在此,上一篇文章就是受这篇文章启发,这次干脆都翻译过来. 过去的几年中涌现了大量的Objective-C开发者.有些是从动态语言转过来的,比如Ruby或Python,有些是从强类型语 ...

  3. OC动态特性

    今天是2.15周日,快要过年了,我以一个实习生的身份在公司工作了快要两个月了吧,什么是北漂,北漂就是感觉生活节奏变了,以前困了可以上课睡觉,累了可以回家休息数周,人际交往乏了,可以躲起来看着窗外的雨或 ...

  4. 深入Objective-C的动态特性 Runtime

    Objective-C具有相当多的动态特性,基本的,也是经常被提到和用到的有动态类型(Dynamic typing),动态绑定(Dynamic binding)和动态加载(Dynamic loadin ...

  5. Objective-C的动态特性

    最近几年中涌现了大量的Objective-C开发者.有些是从动态语言转过来的,比如Ruby或Python,有些是从强类型语言转过来的,如Java或C#,当然也有直接以Objective-C作为入门语言 ...

  6. (译)Objective-C的动态特性

    这是一篇译文,原文在此,上一篇文章就是受这篇文章启发,这次干脆都翻译过来. 过去的几年中涌现了大量的Objective-C开发者.有些是从动态语言转过来的,比如Ruby或Python,有些是从强类型 ...

  7. JS动态特性

    var arr=[]; arr['js']='jquery'; arr['css']='oocss'; var obj={}; for(var i in arr) { obj[i]=arr[i]; } ...

  8. Ruby基础类型,动态特性,代码块

    #Ruby内置基础数据类型 NilClass,TureClass,FalseClass,Time,Date,String,Range,Struct,Array,Hash #Numerice 1.分为I ...

  9. 最新iOS 6 in Xcode4.5新特性——Storyboard和属性自动绑定

    最新iOS 6 in Xcode4.5新特性编程之二(上)——Storyboard和属性自动绑定 从Xcode 4.3开始,Storyboard 就是iOS 5和iOS 6中令人兴奋的一个新特性,他将 ...

随机推荐

  1. Android -- 获取汉字的首字母

    转换                                                                                             获取一个汉 ...

  2. cygwin chmod 失效

    问题背景 为了在 Cygwin 下使用之前最喜爱的 screen 命令, 安装 Cygwin 时就选上了 screen 来运行一把 ganiks.liu@MAMIS-Gaiks-Liu /tmp $ ...

  3. Dijkstra算法亲自实践

    按路径长度递增次序产生算法: 把顶点集合V分成两组: (1)S:已求出的顶点的集合(初始时只含有源点V0) (2)V-S=T:尚未确定的顶点集合 将T中顶点按递增的次序加入到S中,保证: (1)从源点 ...

  4. 【转载】Mybatis多参数查询映射

    转载地址:http://www.07net01.com/zhishi/402787.html 最近在做一个Mybatis的项目,由于是接触不久,虽然看了一下资料,但在实际开发中还是暴 露了很多问题,其 ...

  5. ffmpeg iOS 编译

    编译模拟器版本1 到https://github.com/yuvi/gas-preprocessor下载gas-preprocessor.p并拷贝到/usr/sbin目录中2 下载ffmpeg源码.h ...

  6. Connection reset by peer: socket write error 连数据库出现改错

    1.网络原因 2.从池中获取连接后没有释放到池中导致的

  7. 2014 ACM/ICPC Asia Regional Xi'an Online Paint Pearls

    传说的SB DP: 题目 Problem Description Lee has a string of n pearls. In the beginning, all the pearls have ...

  8. HDU 5014Number Sequence

    思路: 对于一个二进制100011: 尽量将填满:填成111111: 然后有一个很好算的方法 gets(n)表示二进制下N有多少位,N^X=(111111)2 X=111111^N; 其实答案可以直接 ...

  9. 添加hive默认配置hiverc

    可以在$HOME中加一个.hiverc文件,并在里面配置hive启动的一些参数. Fro example: http://hadooped.blogspot.com/2013/08/hive-hive ...

  10. ObjectStore onFetch方法获取记录总数

    转自:http://blog.csdn.net/earthhour/article/details/38686029 ObjectStore onFetch方法获取记录总数 require(['doj ...