Objective-C笔记

为什么突然要搞ObjectiveC?因为清明比较闲,两三天正好用来学习下iOS的逆向分析。 逆向的第一步当然是先从正向了解,否则给你源代码都看不懂,反编译出来的就更别提了。 因此本篇文章作为简单学习ObjC的记录,不会涉及太深入的语法特性,简而言之就是——够用就行。

什么是Objective-C

Objective-C,简称OC,是一种通用、高级、面向对象的编程语言。它扩展了标准的ANSI C编程语言, 将Smalltalk式的消息传递机制加入到ANSI C中。当前主要支持的编译器有GCC和Clang(采用LLVM作为后端)。 Objective-C的商标权属于苹果公司,苹果公司也是这个编程语言的主要开发者。 苹果在开发NeXTSTEP操作系统时使用了Objective-C,之后被OS X和iOS继承下来。 现在Objective-C与Swift是OS X和iOS操作系统、及与其相关的API、Cocoa和Cocoa Touch的主要编程语言。

Objective-C是C语言的严格超集。这意味着任何C语言程序不经修改就可以直接通过Objective-C编译器, 在Objective-C中使用C语言代码也是完全合法的。Objective-C被描述为盖在C语言上的薄薄一层, 因为Objective-C的原意就是在C语言主体上加入面向对象的特性。OC项目中常用的拓展名如下:

扩展名 内容类型
.h 头文件。头文件包含类,类型,函数和常数的声明。
.m 源代码文件。这是典型的源代码文件扩展名,可以包含 Objective-C 和 C 代码。
.mm 源代码文件。带有这种扩展名的源代码文件,除了可以包含Objective-C和C代码以外还可以包含C++代码。仅在你的Objective-C代码中确实需要使用C++类或者特性的时候才用这种扩展名。

Hello, World!

学习任何一门语言之前,基本都需要做的就是编写并运行一个HelloWorld程序,对于OC而言则是如下:

m

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{
    @autoreleasepool {
        NSLog (@"Hello, World!");
    }
    return 0;
}

使用clang进行编译:

bash

clang -framework Foundation hello.m -o hello

运行:

text

$ ./hello
2019-04-05 09:33:22.579 hello[75742:3312942] Hello, World!

So easy!我们学习Objective-C时记住要重点关注概念而不是具体的语言细节,避免陷入学而无用的境地。

关键概念

Objective-C最大的特色是承自Smalltalk的消息传递模型(message passing), 此机制与今日C++式之主流风格差异甚大。 Objective-C里,与其说对象互相调用方法, 不如说对象之间互相传递消息更为精确。此二种风格的主要差异在于调用方法/消息传递这个动作。 C++里类别与方法的关系严格清楚,一个方法必定属于一个类别,而且在编译时(compile time) 就已经紧密绑定,不可能调用一个不存在类别里的方法。但在Objective-C,类别与消息的关系比较松散, 调用方法视为对对象发送消息,所有方法都被视为对消息的回应。所有消息处理直到运行时(runtime) 才会动态决定,并交由类别自行决定如何处理收到的消息。也就是说,一个类别不保证一定会回应收到的消息, 如果类别收到了一个无法处理的消息,程序只会抛出异常,不会出错或崩溃。

C++里,送一个消息给对象(或者说调用一个方法)的语法如下:

cpp