OC语言的特性(一)-消息传递与调用函数的表现形式

咱们在初学Objective-C时,都会以为ObjC中的消息传递和其余语言的调用函数差很少,只是在OC中,方法调用用消息传递这一律念来代替。c++

那么到底怎样区别OC中的消息传递与其余语言的调用函数呢。程序员

可使用C语言与OC语言进行一下对比。编程

C语言示例数据结构

 

//声明一个函数,用来获取两个整型值的中较大的值int max(int a,int b); 
int main(int argc, const char * argv[])
{    //调用函数,获取4,6两个整型值的最大值    int result = max(4,6);    
    //打印结果
    printf("4与6两个数的较大的值是:%d",result);    return 0;
}

 

编译运行程序以后,编译器会提示以下错误app

Undefined symbols for architecture x86_64:
  "_max", referenced from:
      _main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

在如上的例子中,咱们可以体会到调用函数的语言在声明完函数后,若是没有实现函数,程序是没法编译经过的。函数

那么咱们接下来看工具

OC的例子ui

 

#import <Foundation/Foundation.h>@interface Function : NSObject//声明一个类方法,用来获取两个整型值的最大值+ (int)max:(int)v1 :(int)v2;@end#import "Function.h"@implementation Function@end

 

只使用Xcode工具的build功能(Command+B),咱们可以看到程序是能够编译经过的,可是会有一个黄色的警告spa

Method definition for 'max::' not found!

只有当程序运行以后才会出现以下的崩溃信息指针

+[Function max::]: unrecognized selector sent to class 0x1000010f8*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[Function max::]: unrecognized selector sent to class 0x1000010f8'*** First throw call stack:
(    0   CoreFoundation                      0x00007fff8ea9925c __exceptionPreprocess + 172    1   libobjc.A.dylib                     0x00007fff88555e75 objc_exception_throw + 43    2   CoreFoundation                      0x00007fff8ea9c02d +[NSObject(NSObject) doesNotRecognizeSelector:] + 205    3   CoreFoundation                      0x00007fff8e9f7272 ___forwarding___ + 1010    4   CoreFoundation                      0x00007fff8e9f6df8 _CF_forwarding_prep_0 + 120    5   SendMethod                          0x0000000100000f24 main + 68    6   libdyld.dylib                       0x00007fff8a8f95fd start + 1)
libc++abi.dylib: terminating with uncaught exception of type NSException

经过这种形式的对比,相信你们应该对消息传递和调用函数的形式上的区别应该可以看出来了。

对,消息传递调用函数对于程序员来讲最大的区别就在于源代码编译的过程当中是否可以编译经过.

解释消息传递机制的原理就要用到OC语言中的运行时系统(Runtime)了.

     运行时系统是一个提供一系列公开函数接口以及数据结构的动态连接库,这些头文件位于/usr/include/objc。许多这些函数容许你使用纯C语言重写当你写OC代码后编译器作的事情。其余形式的接口则是经过NSObject类中定义的一些方法。这些方法是能够用来实现其余的运行时接口来提升运行效率。可是重写运行时的代码对于使用OC语言进行编程并不是是必须的,可是,少数的运行时函数在一些特殊状况下,对于OC程序仍是颇有用途的。

     接下来,咱们一块儿看一下这些函数。

  Objc_msgSend()函数举例

  

#import <Foundation/Foundation.h>@interface Function : NSObject//声明一个类方法,用来获取两个整型值的最大值+ (int)max:(int)v1 :(int)v2;@end#import "Function.h"@implementation Function+ (int)max:(int)v1 :(int)v2
{    return v1 > v2 ? v1:v2;
}@end

 

根据以上的Function类,使用objc_msgSend()这种c语言的函数完成oc方法的调用。

 

    //获取4,6两个整型值的最大值    int result = (int)objc_msgSend([Function class], @selector(max::),4,6);    
    //打印结果
    NSLog(@"4,6的最大值是:%d",result);

 

消息传递函数为动态绑定提供全部必要的内容:

  • 首先,它找到选择器调用的过程(方法实现)。因为同一个方法在不一样的类中可能有不一样的实现,这个精确的调用过程依赖于接收者所属于的类。

  • 而后,它会调用这个过程,传递接收者对象(一个指向其数据的指针),以及消息中定义的那些参数。

  • 最后,它传递过程调用的返回值做为它自身的返回值。

  • 注意:编译器会自动调用消息传递函数。你不该该在本身的代码中直接调用该方法。

相关文章
相关标签/搜索