Objective-C 与 Swift 对比:语法、容器、控制流及类型系统解析
1. 字符串创建
在 Swift 和 Objective-C 中都能使用双引号创建字符串实例,但在 Objective-C 里,需在双引号前加上
@
符号。例如:
// Swift
var swiftString = "Hello"
// Objective-C
NSString *objcString = @"Hello";
2. 类实例化
Objective-C 的类系统规定,不能创建值类型的类实例,所有实例都必须由引用类型引用。比如,不能创建普通的
NSString
,而必须使用
NSString*
指针。
3. 容器
Objective-C 拥有与 Swift 相同的核心容器,不过命名略有不同,且所有容器都是引用类型。
3.1 数组
-
初始化
:
- Swift 中:
var array = [Int]()
- Objective-C 有多种初始化方式:
// 分步初始化
NSArray *array = [NSArray alloc];
array = [array init];
// 链式初始化
NSArray *array = [[NSArray alloc] init];
// 使用 new 方法
NSArray *array = [NSArray new];
Objective-C 初始化新实例需分两步,先分配内存,再进行初始化。
alloc
用于分配内存,
init
用于设置默认值。链式调用更简洁,但要注意
alloc
可能返回
nil
,不过在 Objective-C 中对
nil
调用方法会返回
nil
。
-
类型
:Objective-C 的
NSArray
能包含任意非 C 类型的混合类型,编译器不会进行类型检查,这可能导致代码出错。
-
添加和移除元素
:
NSArray
是不可变的,若要添加或移除元素,需使用
NSMutableArray
。
NSMutableArray *array = [NSMutableArray new];
[array addObject:@"Hello World!"];
[array removeObjectAtIndex:0];
-
访问元素
:有两种方式,使用
objectAtIndex:方法或方括号。
NSString *myString = [array objectAtIndex:0];
NSString *myString = array[0];
-
数组字面量
:Objective-C 也有数组字面量,以
@符号开头,元素用方括号括起来。
NSArray *array = @[@"one", @"two", @"three"];
3.2 字典
- 初始化 :
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
NSDictionary *dict2 = [NSDictionary new];
-
设置值
:使用
setObject:forKey:方法。
[dict setObject:@"World" forKey:@"Hello"];
-
访问值
:使用
objectForKey:方法或方括号。
NSString *myString = [dict objectForKey:@"Hello"];
NSString *myString2 = dict[@"Hello"];
-
移除值
:使用
removeObjectForKey:方法。
[dict removeObjectForKey:@"Hello"];
- 字典字面量 :Objective-C 的字典字面量用花括号声明。
NSDictionary *dict3 = @{@1: @"one", @2: @"two", @3: @"three"};
以下是 Objective-C 数组和字典操作的流程图:
graph TD;
A[开始] --> B[初始化数组或字典];
B --> C{是否可变};
C -- 是 --> D[添加/移除元素];
C -- 否 --> E[不可添加/移除];
D --> F[访问元素];
E --> F;
F --> G[结束];
4. 控制流
Objective-C 有许多与 Swift 相同的控制流范式。
4.1 输出
Swift 使用
print
函数,Objective-C 使用
NSLog
函数,且不支持字符串插值。
var name = "Sarah"
println("Hello \(name)")
NSString *name = @"Sarah";
NSLog(@"Hello %@", name);
4.2 条件语句
Objective-C 的条件语句与 Swift 类似,但必须使用括号。
var invitees = ["Sarah", "Jamison", "Roana"]
if invitees.count > 20 {
print("Too many people invited")
}
NSArray *invitees = @[@"Sarah", @"Jamison", @"Roana"];
if (invitees.count > 20) {
NSLog(@"Too many people invited");
}
4.3 开关语句
Objective-C 的开关语句远不如 Swift 强大,只能进行相等比较,且默认情况下一个 case 会流入下一个 case,需使用
break
关键字跳出。
switch invitees.count {
case 1:
print("One person invited")
case 2:
print("Two people invited")
default:
print("More than two people invited")
}
switch (invitees.count) {
case 1:
NSLog(@"One person invited");
break;
case 2:
NSLog(@"Two people invited");
break;
default:
NSLog(@"More than two people invited");
break;
}
4.4 循环语句
- while 循环 :与 Swift 类似,但 Objective-C 必须使用括号。
var index = 0
while index < invitees.count {
print("\(invitees[index]) is invited");
index++
}
int index = 0;
while (index < invitees.count) {
NSLog(@"%@ is invited", invitees[index]);
index++;
}
-
for-in 循环
:Objective-C 中需指定循环变量的类型,且遍历
NSDictionary时只能获取键。
var showsByGenre = [
"Comedy": "Modern Family",
"Drama": "Breaking Bad"
]
for (genre, show) in showsByGenre {
print("\(show) is a great \(genre)")
}
NSDictionary *showsByGenre=@{
@"Comedy":@"Modern Family",
@"Drama":@"Breaking Bad"
};
for (NSString *genre in showsByGenre) {
NSLog(@"%@ is a great %@", showsByGenre[genre], genre);
}
-
for 循环
:Objective-C 没有范围类型,若要遍历数字范围,需使用
for循环。
for number in 1 ... 10 {
print(number)
}
for (int number = 1; number <= 10; number++) {
NSLog(@"%i", number);
}
5. 函数
- 无参数无返回值函数 :
func sayHello() {
print("Hello World!");
}
sayHello()
void sayHello() {
NSLog(@"Hello World!");
}
sayHello();
Objective-C 函数以返回类型开头,而非
func
关键字。
-
有参数有返回值函数
:
func addInviteeToListIfSpotAvailable(
invitees: [String],
newInvitee: String
) -> [String] {
if invitees.count >= 20 {
return invitees
}
return invitees + [newInvitee]
}
addInviteeToListIfSpotAvailable(invitees, newInvitee: "Roana")
NSArray *addInviteeToListIfSpotAvailable(
NSArray *invitees,
NSString *newInvitee
) {
if (invitees.count >= 20) {
return invitees;
}
NSMutableArray *copy = [invitees mutableCopy];
[copy addObject:newInvitee];
return copy;
}
addInviteeToListIfSpotAvailable(invitees, @"Roana");
Objective-C 函数在参数定义上需先指定类型,且处理数组时需显式复制并确保副本可变。
6. 类型
Objective-C 的类型系统与 Swift 有所不同,结构和枚举来自 C,只有类和类别来自 Objective-C 扩展。
6.1 结构体
Objective-C 的结构体只是为一组基本类型命名,不能包含方法和 Objective-C 类型。
struct Cylinder {
var radius: Int
var height: Int
}
var c = Cylinder(radius: 10, height: 10)
typedef struct {
int radius;
int height;
} Cylinder;
Cylinder c;
c.radius = 10;
c.height = 5;
6.2 枚举
Objective-C 的枚举是表示有限相关可能值的简单机制。
enum PrimaryColor {
case Red
case Green
case Blue
}
enum PrimaryColor {
Red,
Green,
Blue
};
以下是 Swift 和 Objective-C 主要差异的对比表格:
| 对比项 | Swift | Objective-C |
| ---- | ---- | ---- |
| 字符串创建 | 直接用双引号 | 双引号前加
@
|
| 类实例化 | 普通实例 | 必须使用指针 |
| 数组初始化 | 简洁语法 | 分步或链式初始化 |
| 数组类型 | 强类型检查 | 无类型检查 |
| 字典字面量 | 方括号 | 花括号 |
| 控制流括号 | 可选 | 必须 |
| 开关语句 | 功能强大 | 只能相等比较 |
| 函数定义 |
func
开头 | 返回类型开头 |
| 结构体 | 类似类 | 基本类型集合 |
| 枚举 | 功能丰富 | 简单表示 |
综上所述,Objective-C 和 Swift 在语法、容器、控制流、函数和类型系统等方面存在诸多差异。了解这些差异有助于开发者在不同场景下选择合适的语言进行开发。
Objective-C 与 Swift 对比:语法、容器、控制流及类型系统解析
7. 详细对比总结
为了更清晰地展示 Swift 和 Objective-C 在各个方面的差异,我们再次梳理并以列表形式呈现:
-
字符串方面
:
- Swift 直接使用双引号创建字符串,代码简洁直观。
- Objective-C 需在双引号前添加
@
符号,这是其特定的语法要求。
-
类实例化
:
- Swift 可以创建普通的类实例,使用方便。
- Objective-C 所有实例必须通过引用类型(指针)来引用,不能创建值类型的类实例。
-
容器操作
:
-
数组
:
- Swift 数组初始化语法简洁,且具有强类型检查,能有效避免类型相关的错误。
- Objective-C 的
NSArray
初始化方式多样,包括分步、链式和使用
new
方法,但编译器不进行类型检查,可能导致运行时错误。
NSArray
不可变,需使用
NSMutableArray
进行元素的添加和移除操作。
-
字典
:
- Swift 字典字面量使用方括号,语法清晰。
- Objective-C 字典字面量使用花括号,同样要注意键和值的类型处理。
-
控制流语句
:
-
条件语句
:Swift 的括号是可选的,代码更加灵活;Objective-C 必须使用括号。
-
开关语句
:Swift 的开关语句功能强大,可以处理范围、任意条件等;Objective-C 只能进行相等比较,且默认 case 会流入下一个 case,需使用
break
跳出。
-
循环语句
:
-
while
循环:Swift 括号可选,Objective-C 必须使用括号。
-
for-in
循环:Swift 可以直接遍历键值对;Objective-C 需指定类型,且遍历字典时只能获取键。
-
for
循环:Swift 有范围类型,遍历数字范围方便;Objective-C 没有范围类型,需使用传统的
for
循环。
-
函数定义
:
- Swift 函数以
func
关键字开头,参数类型在参数名之后。
- Objective-C 函数以返回类型开头,参数类型在参数名之前。
-
类型系统
:
-
结构体
:Swift 的结构体类似类,功能丰富;Objective-C 的结构体只是基本类型的集合,不能包含方法和 Objective-C 类型。
-
枚举
:Swift 枚举功能丰富,可以关联值、实现方法等;Objective-C 枚举只是简单表示有限的相关可能值。
8. 实际应用中的考虑因素
在实际开发中,选择使用 Swift 还是 Objective-C 需要综合考虑多方面因素:
-
项目需求
:如果是新开发的项目,且对性能和开发效率有较高要求,Swift 是更好的选择,因为它具有现代的语法、强类型检查和丰富的标准库。如果是维护旧的项目,可能需要继续使用 Objective-C。
-
团队技术栈
:如果团队成员熟悉 Swift,那么使用 Swift 进行开发可以提高开发效率;如果团队成员对 Objective-C 有深入的了解,那么在一定程度上可以继续使用 Objective-C。
-
兼容性
:Objective-C 是苹果早期的开发语言,与旧的代码库和框架有更好的兼容性。Swift 虽然在不断发展,但在某些特定的旧项目中可能会存在兼容性问题。
9. 代码示例总结与回顾
以下是我们前面提到的代码示例的再次总结,方便大家回顾:
// Swift 代码示例
// 字符串创建
var swiftString = "Hello"
// 数组初始化
var array = [Int]()
// 字典初始化
var showsByGenre = [
"Comedy": "Modern Family",
"Drama": "Breaking Bad"
]
// 条件语句
var invitees = ["Sarah", "Jamison", "Roana"]
if invitees.count > 20 {
print("Too many people invited")
}
// 开关语句
switch invitees.count {
case 1:
print("One person invited")
case 2:
print("Two people invited")
default:
print("More than two people invited")
}
// 循环语句
// while 循环
var index = 0
while index < invitees.count {
print("\(invitees[index]) is invited");
index++
}
// for-in 循环
for (genre, show) in showsByGenre {
print("\(show) is a great \(genre)")
}
// for 循环
for number in 1 ... 10 {
print(number)
}
// 函数定义
func sayHello() {
print("Hello World!");
}
sayHello()
func addInviteeToListIfSpotAvailable(
invitees: [String],
newInvitee: String
) -> [String] {
if invitees.count >= 20 {
return invitees
}
return invitees + [newInvitee]
}
addInviteeToListIfSpotAvailable(invitees, newInvitee: "Roana")
// 结构体
struct Cylinder {
var radius: Int
var height: Int
}
var c = Cylinder(radius: 10, height: 10)
// 枚举
enum PrimaryColor {
case Red
case Green
case Blue
}
// Objective-C 代码示例
// 字符串创建
NSString *objcString = @"Hello";
// 数组初始化
NSArray *array = [[NSArray alloc] init];
NSMutableArray *mutableArray = [NSMutableArray new];
[mutableArray addObject:@"Hello World!"];
// 字典初始化
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:@"World" forKey:@"Hello"];
// 条件语句
NSArray *invitees = @[@"Sarah", @"Jamison", @"Roana"];
if (invitees.count > 20) {
NSLog(@"Too many people invited");
}
// 开关语句
switch (invitees.count) {
case 1:
NSLog(@"One person invited");
break;
case 2:
NSLog(@"Two people invited");
break;
default:
NSLog(@"More than two people invited");
break;
}
// 循环语句
// while 循环
int index = 0;
while (index < invitees.count) {
NSLog(@"%@ is invited", invitees[index]);
index++;
}
// for-in 循环
NSDictionary *showsByGenre=@{
@"Comedy":@"Modern Family",
@"Drama":@"Breaking Bad"
};
for (NSString *genre in showsByGenre) {
NSLog(@"%@ is a great %@", showsByGenre[genre], genre);
}
// for 循环
for (int number = 1; number <= 10; number++) {
NSLog(@"%i", number);
}
// 函数定义
void sayHello() {
NSLog(@"Hello World!");
}
sayHello();
NSArray *addInviteeToListIfSpotAvailable(
NSArray *invitees,
NSString *newInvitee
) {
if (invitees.count >= 20) {
return invitees;
}
NSMutableArray *copy = [invitees mutableCopy];
[copy addObject:newInvitee];
return copy;
}
addInviteeToListIfSpotAvailable(invitees, @"Roana");
// 结构体
typedef struct {
int radius;
int height;
} Cylinder;
Cylinder c;
c.radius = 10;
c.height = 5;
// 枚举
enum PrimaryColor {
Red,
Green,
Blue
};
10. 开发流程对比
以下是使用 Swift 和 Objective-C 进行简单项目开发的流程对比流程图:
graph LR;
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;
A([开始项目]):::startend --> B{选择语言}:::decision;
B -- Swift --> C(定义变量和容器):::process;
B -- Objective-C --> D(定义变量和指针):::process;
C --> E(编写控制流语句):::process;
D --> E;
E --> F(定义函数):::process;
F --> G(处理类型系统):::process;
G --> H(测试和调试):::process;
H --> I([完成项目]):::startend;
11. 总结
通过对 Swift 和 Objective-C 在语法、容器、控制流、函数和类型系统等方面的详细对比,我们可以看到它们各有优缺点。Swift 作为一门现代的编程语言,具有简洁的语法、强类型检查和丰富的功能,适合新的项目开发和追求高效开发的场景。Objective-C 作为苹果早期的开发语言,具有悠久的历史和广泛的应用,在旧项目维护和与旧代码库兼容方面具有优势。开发者应根据项目的具体需求、团队技术栈和兼容性要求等因素,合理选择使用的编程语言,以达到最佳的开发效果。
希望本文能帮助开发者更好地理解 Swift 和 Objective-C 的差异,在实际开发中做出更明智的选择。
超级会员免费看
281

被折叠的 条评论
为什么被折叠?



