题型复现
你怎么理解OC这门语言?
OC的动态性表现在那些方面?
他有什么优缺点呢?
Why Objective-C
我们都知道Objective-C是乔老帮主带着NexTSTEP回归苹果后为苹果公司注入的新生力量,也正是这一股新生力量将苹果推向了高峰,不管是在PC领域还是在移动设备领域。那么,选择Objective-C的理由又是什么呢?
我们也可以参看官档是怎么描述理由的,这里我小作翻译而已。
选择OC的原因很多。首先,他是一种面向对象的语言。打包在Cocoa框架中的功能只能通过面向对象的技术来使用。其次,由于OC是标准ANSI Cc的扩展,所以现有的C程序可以得到OC框架的良好支持。因为Objective-C包含C,所以在Objective-C中工作时可以获得C的所有好处。你可以选择何时以面向对象的方式执行某些操作(例如定义新类)以及何时坚持使用面向过程编程(定义结构和某些函数而不是类)。
而且,OC是一门基本简单的语言。他语法小巧,明确,同时更易于学习。面向对象编程往往因其自省的术语和对抽象的强调,使得新的学习者的学习曲线更加陡峭。但像OC这样组织良好的语言对于成为一名熟练的面向对象开发者意味着更少的困难。
和其他基于C的面向对象语言相比,OC非常动态化。编译器忽略了大量有关对象本身的处理,以便他们在运行时再进行处理。这样在编译器做的很多事情就都推迟到了运行时。动态特性赋予了OC不同寻常的灵活性和强大的功能。例如,它产生的两个其他面向对象语言都没有的好处:
其一是OC支持开放式的动态绑定,这种风格可以容纳交互式用户界面的简单架构。消息不一定受限于接受类甚至是方法名称,因而软件框架允许你在运行时选择某些设计上的自由。
其二,动态能够构建复杂的开发工具。运行时的接口提供有关正在运行的应用程序相关信息的访问,因而使对监控程序的开发成为可能,以及其他一些干预和揭示底层结构和活动的工具。
上面摘自官档,我想这些已经足以作为我们回答第一个问题的基础。
动态性
OC是一门动态语言,上面也略有提到他的动态性。OC的动态性主要变现在三个方面。
1.动态类型(Dynamic Typing)
动态类型是指对象指针的动态性,体现就是OC里的id类型。我们知道id类型可以指向任意类型的OC对象,它具体指向什么类型是在运行时确定的。
最司空见惯的应用就是Delegate的实现,我们并不知道将来遵循当前协议的是哪个类,所以在声明delegate的时候往往使用id作为它的的类型。
但是,我们能用静态类型还是要尽量使用静态类型。毕竟这样,编译的时候编译器能对代码做类型检查。
2.动态绑定(Dynamic Binding)
动态绑定呢,主要是指对象的方法和成员变量在运行时才会得到唯一确定。例如我们熟悉的Java,某个对象方法和成员变量在编译的时候就得到了唯一确定,之后就不能做出改变。而OC呢,在编译之后还是可以动态新增成员变量或方法或者改变某些方法的执行逻辑。动态绑定就是辣么神奇。
首先看成员变量的动态性,就是指我们在运行时可以为对象动态地新增成员变量。当然这个情况必须发生在objc_allocateClassPair之后objc_registClassPair之前。
动态添加方法的时机和条件同上。
这里需要重点理解的是动态地改变方法执行的逻辑。这里就有必要谈谈OC方法的本质其实是消息的传递,OC中所有的方法调用在底层都会走消息传递objc_msgSend函数。所谓改变方法执行的逻辑,主要体现在三点:
- 1.动态地交换原有方法
- 2.消息转发
- 3.unrecongized selector的无crash处理
这三点这里暂且提及一下,以后的篇章会详述。这里只是用以说明OC的动态绑定特性。
3.动态加载(Dynamic Loading)
动态加载主要是指资源的动态加载,我们都知道iOS开发中图片的类型有@1x, @2x, @3x,程序使用图片会根据当前的设备自动加载对应的图片类型。
OC优缺点
优点
- 1.动态特性
- 2.兼容C/C++
- 3.有Cateogory等扩展
- 4.支持继承
缺点
- 1.不支持命名空间(可以添加前缀来解决该问题)
- 2.不支持多继承(NSProxy+消息转发可以模拟实现多继承)
- 3.不支持运算符重载
- 4.很多编译时优化不支持,例如内联函数
扩展:编程语言的分类
我们知道OC是一门动态语言。那么什么又是动态语言呢?与之对应的静态语言又是什么呢?
动态语言是指数据类型的检查是在运行时做的。典型代表OC,Python,Ruby等。
静态语言是指数据类型的检查是在编译时做的。典型代表C++,Java,C#等。
另外,编程语言还可以分为编译语言,解释语言和混合语言(相对于编译型和解释型)。
编译语言是先将源代码编译生机器指令,再由机器运行机器码。典型代表OC,C/C++,Swift等。
解释语言是先将源代码翻译成中间代码,再由解释器对其解释运行。典型代表JavaScript,Python,Php等。
混合语言整合以上两种类型,取其精华弃其糟粕。典型代表Java,C#等。
其实之外,按别的角度又能分为强类型定义语言和弱类型定义语言。
强类型定义语言是指数据类型的定义有严格的区分。一旦某个变量被定义为某种数据类型,如果不经过强制转换那么他永远就是这个类型了。他是类型安全的(编译器会做检查)。典型代表Java,Python等。
弱类型定义语言是指变量定义时数据类型可以被忽略,在赋值的时候被确定赋予哪种数据类型。他是类型不安全的(编译器不做检查)。典型代表JavaScript,Php等。
以上几种对语言的分类只是从不同角度进行的,跨角度分类之间没有必然联系。
思考题
1.C是强还是弱类型?OC呢?
2.以下代码编译会报错吗?如果不会,其中obj在编译和运行时分别是什么类型?为什么NSString *obj =[ [NSData alloc] init ];
3.instancetype和id类型有什么区别?
4.OC项目怎么引用C代码?C++呢?
--------------------------------------------------------------20190526午后
我们所写的代码
所选择的态度
以及所投入的时间和经历
都将成为通向黄金程序猿的
垫脚石-----------------------------非著名八线互联网九流程序猿 chaors