OC语言的特性(一)-消息传递与调用函数的表现形式
我们在初学Objective-C时,都会觉得ObjC中的消息传递和其他语言的调用函数差不多,只是在OC中,方法调用用消息传递这一概念来代替。
那么到底怎样区别OC中的消息传递与其他语言的调用函数呢。
可以使用C语言与OC语言进行一下对比。
C语言示例
//声明一个函数,用来获取两个整型值的中较大的值
int max(int a,int b); int main(int argc, const char * argv[])
{ //调用函数,获取4,6两个整型值的最大值
int result = max(,); //打印结果
printf("4与6两个数的较大的值是:%d",result);
return ;
}
编译运行程序之后,编译器会提示如下错误
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的例子
#import <Foundation/Foundation.h> @interface Function : NSObject //声明一个类方法,用来获取两个整型值的最大值
+ (int)max:(int)v1 :(int)v2; @end #import "Function.h" @implementation Function @end
只使用Xcode工具的build功能(Command+B),我们能够看到程序是可以编译通过的,但是会有一个黄色的警告
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:
(
CoreFoundation 0x00007fff8ea9925c __exceptionPreprocess +
libobjc.A.dylib 0x00007fff88555e75 objc_exception_throw +
CoreFoundation 0x00007fff8ea9c02d +[NSObject(NSObject) doesNotRecognizeSelector:] +
CoreFoundation 0x00007fff8e9f7272 ___forwarding___ +
CoreFoundation 0x00007fff8e9f6df8 _CF_forwarding_prep_0 +
SendMethod 0x0000000100000f24 main +
libdyld.dylib 0x00007fff8a8f95fd start +
)
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::),,); //打印结果
NSLog(@"4,6的最大值是:%d",result);
消息传递函数为动态绑定提供所有必要的内容:
- 首先,它找到选择器调用的过程(方法实现)。由于同一个方法在不同的类中可能有不同的实现,这个精确的调用过程依赖于接收者所属于的类。
- 然后,它会调用这个过程,传递接收者对象(一个指向其数据的指针),以及消息中定义的那些参数。
- 最后,它传递过程调用的返回值作为它自身的返回值。
- 注意:编译器会自动调用消息传递函数。你不应该在自己的代码中直接调用该方法。
OC语言的特性(一)-消息传递与调用函数的表现形式的更多相关文章
- iOS - OC 语言新特性
前言 相对于 Java,OC 语言是一门古老的语言了,而它又是一门不断发展完善的语言.一些新的编译特性,为 OC 语言带来了许多新的活力.在 Xcode7 中,iOS9 的 SDK 已经全面兼容了 O ...
- OC 语言新特性
前言 相对于 Java,OC 语言是一门古老的语言了,而它又是一门不断发展完善的语言.一些新的编译特性,为 OC 语言带来了许多新的活力. 在 Xcode7 中,iOS9 的 SDK 已经全面兼容了 ...
- 黑马程序员——OC语言 三大特性之多态
Java培训.Android培训.iOS培训..Net培训.期待与您交流! (以下内容是对黑马苹果入学视频的个人知识点总结) 三大特性之一的多态 (一)多态的基本概念 OC对象具有多态性体现在 Per ...
- 黑马程序员——OC语言 三大特性之继承
Java培训.Android培训.iOS培训..Net培训.期待与您交流! (以下内容是对黑马苹果入学视频的个人知识点总结) 三大特性之继承 (一)继承的基本用法 先建立个Animal再用Dog继承前 ...
- OC语言的特性(二)-Block
本篇文章的主要内容 了解何谓block. 了解block的使用方法. Block 是iOS在4.0版本之后新增的程序语法. 在iOS SDK 4.0之后,Block几乎出现在所有新版的API之中,换句 ...
- oc语言--面向对象的三大特性
一.封装 1.什么是封装 在程序上,隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别:将对象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的 ...
- swift调用oc语言文件,第三方库文件或者自己创建的oc文件——简书作者
Swift是怎样调用OC的第三方库的呢?请看下面详情: 情况一: 1.首先打开Xcode,iOS->Application->Single View Application, 选Next. ...
- OC语言-03-OC语言-三大特性
一.封装 1> 封装的定义 隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别 2> 封装的好处 可以通过set方法防止为成员变量设置不合理的值 仅向外部提供公 ...
- Swift基础之Swift调用OC语言文件使用步骤
Swift语言中,有很多封装类并没有,如果需要使用到,就需要桥接OC语言中的类,这时候就需要使用桥接头文件,一下是使用的步骤: 创建一个Swift项目Demo,然后新建一个OC语言的文件 如图: 创建 ...
随机推荐
- 3.1 cron表达式
1.Cron在线生成网址: http://cron.qqe2.com/ http://www.pdtools.net/tools/becron.jsp#cron 2.Cron 概要 3. ...
- phpstudy 安装memcached服务和memcache扩展
memcached安装步骤: 首先,将下载好的memcahed解压到某个文件目录下,例如 C:\memcached 然后,在cmd里,输入"C:\memcached\memcached.ex ...
- HDU 2802 F(N)(简单题,找循环解)
题目链接 F(N) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- android上的JAVA8:使用retrolambda
android上的JAVA8:使用retrolambda posted by juuda 2015年6月3日 下午7:33 under Android Java8引入了lambda表达式,让许多开发者 ...
- Node.js学习 - CallBack Function
Node.js异步编程的直接体现就是回调,Node使用了大量的回调函数,其所有的API都支持回调. 阻塞代码实例(同步) var fs = require("fs"); var d ...
- Linux学习 -- 日志管理
日志服务 rsyslogd CentOS6 取代了原来的syslog rsyslogd 默认启动.自启动 常用命令:lastb.lastlog.last.w.who.users. 系统默认日志 和 ...
- ubuntu虚拟机和主机互ping及secureCRT使用
1.首先使用ifconfig查看IP,如果没有IP的话就配置IP,配置的IP要和主机在一个网段,可以使用ipconfig查看主机(WIN7)的ip地址. 2.根据ifconfig列出的网卡配置IP地址 ...
- 团队开发里频繁使用 git rebase 来保持树的整洁好吗?
用了以后, 树可以非常清晰, 某种程度上便于追踪, 但是 push --force 就多多了,不用呢, 合并没有远程仓库被修改的麻烦, 可是追踪又不清晰... git rebase是对commit h ...
- Zend Optimizer not installed可能原因及解决方法
Zend Optimizer not installed可能原因及解决方法 Optimizer, Zend 在配置php服务器的时候,所有的东西都安装好了,就是浏览一个要求zend的程序的时候,总是提 ...
- 利用php函数mkdir递归创建层级目录
项目开发中免不了要在服务器上创建文件夹,比如上传图片时的目录,模板解析时的目录等.这不当前手下的项目就用到了这个,于是总结了几个循环创建层级目录的方法. php默认的mkdir一次只能创建一层目录,而 ...