编写 iOS 越狱插件:速览 Objective-C

1,562次阅读
没有评论

Objective-C++ 在很长时间内都是 iOS 上的主流编程语言。2014 年 Apple 发布 Swift 之后,这一情况才逐渐改变。但是,在开发 Tweak 时,用得更多的依旧是 Objective-C。因此有必要对 Objective-C 有一个快速的了解。

这里假定你对 C-like 语言有一个较为全面的了解。若你是 C/C++ 的熟练使用者则更好。

简介

Objective-C 是 C 语言的严格超集。即是说,在 C 编译器下能够编译的代码,应当可以不加修改地使用 Objective-C 的编译器来编译。(尽管可能行为不完全相同)另一方面,在 Objective-C 当中,可以混合使用 C 风格的代码。

文件扩展名

头文件实现文件C.h.cC++.h/.hpp.cc/.cpp/.cxxObjective-C.h.mObjective-C++.h.mm

为了兼容 C,我们依然可以使用预处理器指令 #include 来包含头文件。但是 Objective-C 提供了另一选项 #import。它与 #include 的作用几乎完全相同,但可以保证在一个编译单元中每个头文件都只被引入一次。即是说,它起到了传统 C/C++ 变成中 #pragma once 或是 Guard Macro 的作用。

基本类型

Objective-C/C++ 中的基本类型和 C/C++ 中的差不多。几种基本类型在 Objective-C/C++ 中的长度分别是:

  • char: 1B
  • int: 4B
  • float: 4B
  • double: 8B

此外,Objective-C/C++ 中也有 short/long/long long/signed/unsigned 之类的修饰。含义也和 C/C++ 中的相同。

字符串

Objective-C 支持 C-style 字符串,并且也遵循 C 语言当中对引号使用的约定。亦即,使用单引号表示字符(例 'c'),使用双引号表示字符串(null termination)。但在 Objective-C 中也有实现 NSString 类(类似 C++ 中的 std::string 但更强大)。它更常用。

1
2
3
‘c’; // 字符类型字面量
“hello world”; // C-style string
@”hello world”; // Objective-C NSString

此外,NSString 也支持 printf 风格的字符串构造方法,以及支持从 C-style 字符串中构造。

1
2
3
4
5
6
7
8
// construct a NSString object from literal
NSString* myString = @”My Stringn”;

// construct a NSString object from printf formatter
NSString* anotherString = [NSString stringWithFormat: @”%d %s”, 1, @”String”];

// construct a NSString object from C-style string
NSString* fromCString = [NSString stringWithCString: “A C string” encoding: NSASCIIStringEncoding];

逻辑控制

if

Objective-C 中的 if 语句和 C/C++ 中的基本一致。唯独,在 Objective-C 中以 0 表示 false,而以其他值表示 true。例如说,其他任何数值,或是任何字符串,在 Objective-C 中都会被认为是 true

for/while

Objective-C 中的 for/while 和 C 中的完全一致。

函数调用

名称代码风格C/C++对象成员函数调用obj.method(args)Objective-C/C++向对象传递消息[obj method: args]

在 C++/Java 中,类中定义有成员函数/成员方法。我们可以通过类似 obj.method(args) 的方式调用 obj 对象的 method 成员函数。如果 methodobj 所属的类中没有定义,则在编译期就会报错。

Objective-C 则继承了 Smalltalk 的消息传递模型。在这一模型中,调用成员函数被视作是向对象发送一个消息。例如,obj.method(args) 式的调用会被写作是 [obj method: args]。这种写法的意思是,向 obj 这个对象发送名为 method 的消息,args 则是消息附带的参数。与 C++/Java 风格的调用不同,obj 所属的类即便没有定义名为 method 的成员函数,我们在代码中依旧可以向 obj 发送这一消息。Objective-C 的编译器不会为此报错,但在程序执行时则会抛出一个异常。

对比下来,消息传递模型中类和成员函数的关系较为松散,这种调用方式总是在运行期动态绑定。于是,它不需要 C++ 当中的 virtual/override 关键字。当然,这种做法也存在一定额外开销。(显然)

空对象(nil)接受消息后默认不做任何事情。因此向 nil 传递消息是安全的。

类的声明与数据成员

在 C++ 中,我们称之为「声明一个类」。在 Objective-C/C++ 中,我们说「定义类的接口(interface)」。

在 C++ 中,定义一个空的类形如

1
class Foo {};

注意,它不需要继承自一个作为占位符的父类。在 Objective-C/C++ 中,定义一个空类形如

1
2
@interface Foo : NSObject
@end

注意,和 Python 中所有类都继承自 object 类似,Objective-C 中所有类都继承自 NSObject

在 C++ 中,定义一个包含有数据成员的类形如

1
2
3
4
5
6
7
class Foo : public Bar {
protected:
int data;

private:
int private_data;
};

类比在 Objective-C/C++ 中则是

1
2
3
4
5
6
7
8
9
@interface Foo : Bar {
int data;
}
@end

@implementation Foo {
int private_data;
}
@end

Objective-C 的类分为接口(interface)和实现(implementation)。接口部分通常包含了类声明以及其中数据成员的定义,以及相关成员函数的声明。实现部分通常包含了成员函数的实现代码。

注意,C++ 中,class 中的数据成员默认是 private 的;在 Objective-C/C++ 中,@interface 段定义的数据成员默认是 protected 的,@implementation 段定义的数据成员默认是 private 的。为了保持访问控制一致,额外在 C++ 代码中加上了 protected 关键字来指定 data 的访问控制类型。

成员函数

在 C++ 中,成员函数的声明形如

1
2
3
4
5
6
7
8
class Foo : public Bar {
public: // 1.
static void class_method(); // 2.

void instance_method1(); // 3.a
void instance_method2(int p1); // 3.b
void instance_method3(int p1, int p2); // 4.
};

类比在 Objective-C 中,则是如下形式

1
2
3
4
5
6
7
8
@interface Foo: Bar
// 1.
+(void) class_method; // 2.

-(void) instance_method1; // 3.a
-(void) instance_method2: (int) p1; // 3.b
-(void) instance_method3: (int) p1 and: (int) p2; // 4.
@end

首先关注 (1)。在 C++ 中,class 内的访问控制默认是 private。因此,要使声明的成员函数可用,我们需要显式地指明 public。在 Objective-C 中,@interface 段的方法默认是 @public 的。

接下来关注 (2)。在 C++ 中有所谓的 static-成员函数。此类成员函数是属于整个类的,不能修改类的对象内部的数据成员。Objective-C 中也有类似设定,即所谓的类方法(class method)。具体形式是在方法前加上一个 + 记号。

现在关注 (3)。这是典型的成员函数的声明方式。这样的成员函数是与具体的类的对象绑定的,必须要有一个构造好的对象才能执行这些成员函数。在 Objective-C 中,这是所谓的对象方法(instance method),也称为一般方法。

(4) 处也声明了一般意义上的成员函数,但在 Objective-C 这里稍有不同。对 Objective-C 的版本,它的函数全名(签名)是 instance_method3:and:。即是说,在声明时,函数的名称和参数列表交织在一起;每个冒号后面都带有一次参数传递。调用它的时候则类似:[obj instance_method3: 0 and: 1]。这是 Objective-C/C++ 特有的。

属性

尽管我们也可以在 Objective-C 中定义数据成员,但实际上更好的方式是使用属性。例如

1
2
3
@interface Foo: NSObject
@property int age;
@end

它等价于

1
2
3
4
5
6
7
@interface Foo: NSObject
@property int age; // 1.
@end

@implementation Foo
@synthesize age = _age; // 2.
@end

这里,(1) 声明了类 Foo 的一个属性。它的类型是 int,名字是 age。如果没有显式地如 (2) 这样将属性和变量关联起来,则编译器会自动产生一个变量,并做这样的关联。注意,属性的声明应当位于 @interface 段,属性与变量的关联则应放在 @implementation 段。

你也可以使用别的变量与属性进行关联。例如 @synthesize age = internal_age;。这样会将 age 这个属性与 internal_age 这个数据成员进行关联。

声明属性,则编译器会为我们自动生成相应的 setter/getter 方法。例如说,上面的代码,大致相当于会生成这样的代码:

1
2
3
4
5
6
7
8
9
@implementation Foo
-(void) setAge: (int) n {
self->_age = n;
}

-(int) age {
return self->_age;
}
@end

也就是说,通过属性,我们将类的数据成员封装了起来。外部不能直接操作类的数据成员,而要通过 setter/getter 来操作。此外,Objective-C 还为此提供了类似 C++ 中成员访问运算符(.)的语法糖。我们可以写出类似下面的代码

1
2
3
4
5
p.age = 10; // 1.a
[p setAge: 10]; // 1.b

NSLog(@”age is: %d”, p.age); // 2.a
NSLog(@”age is: %d”, [p age]); // 2.b

其中 (1.a) 和 (1.b) 的含义相同,(2.a) 和 (2.b) 的含义也相同。

 Read More 

正文完
可以使用微信扫码关注公众号(ID:xzluomor)
post-qrcode
 0
评论(没有评论)

文心AIGC

2023 年 3 月
 12345
6789101112
13141516171819
20212223242526
2728293031  
文心AIGC
文心AIGC
人工智能ChatGPT,AIGC指利用人工智能技术来生成内容,其中包括文字、语音、代码、图像、视频、机器人动作等等。被认为是继PGC、UGC之后的新型内容创作方式。AIGC作为元宇宙的新方向,近几年迭代速度呈现指数级爆发,谷歌、Meta、百度等平台型巨头持续布局
文章搜索
热门文章
潞晨尤洋:日常办公没必要上私有模型,这三类企业才需要 | MEET2026

潞晨尤洋:日常办公没必要上私有模型,这三类企业才需要 | MEET2026

潞晨尤洋:日常办公没必要上私有模型,这三类企业才需要 | MEET2026 Jay 2025-12-22 09...
“昆山杯”第二十七届清华大学创业大赛决赛举行

“昆山杯”第二十七届清华大学创业大赛决赛举行

“昆山杯”第二十七届清华大学创业大赛决赛举行 一水 2025-12-22 17:04:24 来源:量子位 本届...
MiniMax海螺视频团队首次开源:Tokenizer也具备明确的Scaling Law

MiniMax海螺视频团队首次开源:Tokenizer也具备明确的Scaling Law

MiniMax海螺视频团队首次开源:Tokenizer也具备明确的Scaling Law 一水 2025-12...
清库存!DeepSeek突然补全R1技术报告,训练路径首次详细公开

清库存!DeepSeek突然补全R1技术报告,训练路径首次详细公开

清库存!DeepSeek突然补全R1技术报告,训练路径首次详细公开 Jay 2026-01-08 20:18:...
最新评论
ufabet ufabet มีเกมให้เลือกเล่นมากมาย: เกมเดิมพันหลากหลาย ครบทุกค่ายดัง
tornado crypto mixer tornado crypto mixer Discover the power of privacy with TornadoCash! Learn how this decentralized mixer ensures your transactions remain confidential.
ดูบอลสด ดูบอลสด Very well presented. Every quote was awesome and thanks for sharing the content. Keep sharing and keep motivating others.
ดูบอลสด ดูบอลสด Pretty! This has been a really wonderful post. Many thanks for providing these details.
ดูบอลสด ดูบอลสด Pretty! This has been a really wonderful post. Many thanks for providing these details.
ดูบอลสด ดูบอลสด Hi there to all, for the reason that I am genuinely keen of reading this website’s post to be updated on a regular basis. It carries pleasant stuff.
Obrazy Sztuka Nowoczesna Obrazy Sztuka Nowoczesna Thank you for this wonderful contribution to the topic. Your ability to explain complex ideas simply is admirable.
ufabet ufabet Hi there to all, for the reason that I am genuinely keen of reading this website’s post to be updated on a regular basis. It carries pleasant stuff.
ufabet ufabet You’re so awesome! I don’t believe I have read a single thing like that before. So great to find someone with some original thoughts on this topic. Really.. thank you for starting this up. This website is something that is needed on the internet, someone with a little originality!
ufabet ufabet Very well presented. Every quote was awesome and thanks for sharing the content. Keep sharing and keep motivating others.
热评文章
摩尔线程的野心,不藏了

摩尔线程的野心,不藏了

摩尔线程的野心,不藏了 量子位的朋友们 2025-12-22 10:11:58 来源:量子位 上市后的仅15天...
摩尔线程的野心,不藏了

摩尔线程的野心,不藏了

摩尔线程的野心,不藏了 量子位的朋友们 2025-12-22 10:11:58 来源:量子位 上市后的仅15天...
AI体育教练来了!中国团队打造SportsGPT,完成从数值评估到专业指导的智能转身

AI体育教练来了!中国团队打造SportsGPT,完成从数值评估到专业指导的智能转身

AI体育教练来了!中国团队打造SportsGPT,完成从数值评估到专业指导的智能转身 量子位的朋友们 2025...
AI体育教练来了!中国团队打造SportsGPT,完成从数值评估到专业指导的智能转身

AI体育教练来了!中国团队打造SportsGPT,完成从数值评估到专业指导的智能转身

AI体育教练来了!中国团队打造SportsGPT,完成从数值评估到专业指导的智能转身 量子位的朋友们 2025...
真正面向大模型的AI Infra,必须同时懂模型、系统、产业|商汤大装置宣善明@MEET2026

真正面向大模型的AI Infra,必须同时懂模型、系统、产业|商汤大装置宣善明@MEET2026

真正面向大模型的AI Infra,必须同时懂模型、系统、产业|商汤大装置宣善明@MEET2026 量子位的朋友...