19、Objective-C 与 Swift 对比:语法、容器、控制流及类型系统解析

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 的差异,在实际开发中做出更明智的选择。

通过短时倒谱(Cepstrogram)计算进行时-倒频分析研究(Matlab代码实现)内容概要:本文主要介绍了一项关于短时倒谱(Cepstrogram)计算在时-倒频分析中的研究,并提供了相应的Matlab代码实现。通过短时倒谱分析方法,能够有效提取信号在时间倒频率域的特征,适用于语音、机械振动、生物医学等领域的信号处理故障诊断。文中阐述了倒谱分析的基本原理、短时倒谱的计算流程及其在实际工程中的应用价值,展示了如何利用Matlab进行时-倒频图的可视化分析,帮助研究人员深入理解非平稳信号的周期性成分谐波结构。; 适合人群:具备一定信号处理基础,熟悉Matlab编程,从事电子信息、机械工程、生物医学或通信等相关领域科研工作的研究生、工程师及科研人员。; 使用场景及目标:①掌握倒谱分析短时倒谱的基本理论及其傅里叶变换的关系;②学习如何用Matlab实现Cepstrogram并应用于实际信号的周期性特征提取故障诊断;③为语音识别、机械设备状态监测、振动信号分析等研究提供技术支持方法参考; 阅读建议:建议读者结合提供的Matlab代码进行实践操作,先理解倒谱的基本概念再逐步实现短时倒谱分析,注意参数设置如窗长、重叠率等对结果的影响,同时可将该方法其他时频分析方法(如STFT、小波变换)进行对比,以提升对信号特征的理解能力。
先看效果: https://pan.quark.cn/s/aceef06006d4 OJBetter OJBetter 是一个 Tampermonkey 脚本项目,旨在提升你在各个在线评测系统(Online Judge, OJ)网站的使用体验。 通过添加多项实用功能,改善网站界面用户交互,使你的编程竞赛之旅更加高效、便捷。 ----- 简体中文 ----- 安装 主要功能 安装脚本,你可以获得: 黑暗模式支持:为网站添加黑暗模式,夜晚刷题不伤眼。 网站本地化:将网站的主要文本替换成你选择的语言。 题目翻译:一键翻译题目为目标语言,同时确保不破坏 LaTeX 公式。 Clist Rating 分数:显示题目的 Clist Rating 分数数据。 快捷跳转:一键跳转到该题在洛谷、VJudge 的对应页面。 代码编辑器:在题目页下方集成 Monaco 代码编辑器,支持自动保存、快捷提交、在线测试运行等功能。 一些其他小功能…… [!NOTE] 点击 网页右上角 的 按钮,即可打开设置面板, 绝大部分功能均提供了帮助文本,鼠标悬浮在 ”? 图标“ 上即可查看。 使用文档 了解更多详细信息使用指南,请访问 Wiki 页面。 如何贡献 如果你有任何想法或功能请求,欢迎通过 Pull Requests 或 Issues 我们分享。 改善翻译质量 项目的非中文版本主要通过机器翻译(Deepl & Google)完成,托管在 Crowdin 上。 如果你愿意帮助改进翻译,使其更准确、自然,请访问 Crowdin 项目页面 贡献你的力量。 支持其他OJ? 由于作者精力有限,并不会维护太多的类似脚本, 如果你有兴趣将此脚本适配到其他在线评测系统,非常欢迎,你只需要遵守 GP...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值