杰瑞科技汇

Objective C教程该怎么学?

Objective-C 教程:从入门到实践

目录

  1. 引言:什么是 Objective-C?
  2. 开发环境搭建
  3. Objective-C 核心基础
    • 1 Hello, World!
    • 2 面向对象思想回顾
    • 3 语法特点:C 语言的超集
  4. 核心概念详解
    • 1 接口与实现:.h.m 文件
    • 2 对象的创建与使用
    • 3 消息传递**
    • 4 属性**
    • 5 方法**
    • 6 协议**
    • 7 分类**
    • 8 块**
  5. 内存管理
    • 1 MRC (手动引用计数)
    • 2 ARC (自动引用计数) - 现代 iOS 开发标准
  6. 常用框架与工具
    • 1 Foundation 框架
    • 2 Core Data
    • 3 Xcode 调试技巧
  7. 学习路径与资源推荐
  8. 为什么还要学 Objective-C?

引言:什么是 Objective-C?

Objective-C(简称 ObjC 或 OC)是苹果公司 macOS 和 iOS 操作系统的主要编程语言,它是一门面向对象的语言,其语法独特,融合了 Smalltalk 的消息传递机制和 C 语言的底层能力。

Objective C教程该怎么学?-图1
(图片来源网络,侵删)

主要特点:

  • C 语言的超集:任何合法的 C 语言代码都可以直接在 Objective-C 中编译运行,这使得它非常强大,可以直接操作内存、指针等底层资源。
  • 动态性:与 C++ 或 Java 不同,Objective-C 的很多操作(如方法调用、类型检查)是在运行时决定的,而不是编译时,这赋予了它极高的灵活性。
  • 运行时系统:Objective-C 的强大功能很大程度上依赖于其底层的运行时系统,它负责处理对象、消息分发、方法转发等。
  • 社区与生态:虽然现在 Swift 是苹果官方主推的语言,但海量的现有 iOS/macOS 应用、框架和开源库都是用 Objective-C 编写的,阅读和修改这些代码是必备技能。

开发环境搭建

开发 Objective-C 应用,你只需要安装苹果官方的集成开发环境。

  1. 硬件:一台 Mac 电脑(搭载 Intel 或 Apple Silicon 芯片)。
  2. 软件:从 Mac App Store 免费下载 Xcode,Xcode 不仅包含了编译器、调试器,还集成了 Interface Builder(用于可视化界面设计)、模拟器、性能分析工具等,是开发苹果应用的全能工具。

安装完成后,打开 Xcode,同意许可协议,它就会自动安装所有必要的命令行工具,包括 Clang 编译器和 Objective-C 运行时。


Objective-C 核心基础

1 Hello, World!

创建一个新的 Xcode 项目,选择 "macOS" -> "Command Line App",语言选择 "Objective-C"。

Objective C教程该怎么学?-图2
(图片来源网络,侵删)

main.m 文件中,你会看到如下代码:

#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        NSLog(@"Hello, World!");
    }
    return 0;
}

代码解析:

  • #import <Foundation/Foundation.h>#import#include 的一个增强版,它会自动防止头文件被重复包含。Foundation.h 是 Foundation 框架的核心头文件,包含了所有基本的数据类型、集合类、字符串等。
  • @autoreleasepool { ... }:这是 Objective-C 的自动内存管理池,所有创建的对象都应该放在一个 @autoreleasepool 块中,以便系统能够及时回收不再使用的内存。
  • NSLog(@"Hello, World!");NSLog 是 Foundation 框架提供的日志输出函数,类似于 C 语言的 printf,它会自动在输出后加上时间戳和程序信息,方便调试。 这种形式的字符串是 Objective-C 的字符串字面量,它是一个 NSString 对象,而不是 C 风格的字符数组。

2 面向对象思想回顾

在深入代码前,请务必理解 OOP 的三大支柱:

  • 封装:将数据(属性)和操作数据的方法捆绑在一起,形成一个对象,并对外部隐藏其内部实现细节。
  • 继承:一个类可以继承另一个类的属性和方法,实现代码复用和层次化设计。
  • 多态:不同的对象可以对同一消息做出不同的响应,在 Objective-C 中,这主要通过协议和动态消息传递实现。

3 语法特点:C 语言的超集

Objective-C 保留了 C 语言的所有特性,你可以这样写:

Objective C教程该怎么学?-图3
(图片来源网络,侵删)
int a = 10;
float b = 3.14;
char c = 'A';
int array[5] = {1, 2, 3, 4, 5};

它引入了自己的一套语法来处理面向对象,这些语法都以 符号开头,@interface, @implementation, @property 等。


核心概念详解

这是 Objective-C 学习的重中之重。

1 接口与实现:.h.m 文件

在 Objective-C 中,一个类的定义通常分为两个文件:

  • .h 文件 (Header/Interface File):类的接口文件,它声明了这个类“有什么”(属性)和“能做什么”(方法),它就像一份公共契约,告诉其他代码这个类的功能。
  • .m 文件 (Implementation File):类的实现文件,它详细定义了在 .h 文件中声明的方法的具体实现逻辑。

示例:Person.h

#import <Foundation/Foundation.h>
// @interface 声明一个类,继承自 NSObject
// NSObject 是所有 Objective-C 类的根类
@interface Person : NSObject
// @property 声明一个属性
// @property (nonatomic, copy) NSString *name;
// nonatomic: 非原子性,性能更高
// copy: 对属性赋值时,会进行 copy 操作,确保对象不被意外修改
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age; // assign: 用于基本数据类型
// - 表示实例方法(需要对象才能调用)
// (void) 表示返回类型是 void
- (void)sayHello;
// + 表示类方法(通过类名直接调用,不需要对象)
+ (instancetype)personWithName:(NSString *)name age:(NSInteger)age;
@end

示例:Person.m

#import "Person.h"
@implementation Person
// 实现 sayHello 方法
- (void)sayHello {
    // 使用 self 来引用当前对象
    NSLog(@"Hello, my name is %@ and I'm %ld years old.", self.name, (long)self.age);
}
// 实现 personWithName 类方法
+ (instancetype)personWithName:(NSString *)name age:(NSInteger)age {
    // alloc: 分配内存空间
    // init: 初始化对象
    Person *p = [[self alloc] init];
    p.name = name;
    p.age = age;
    return p;
}
@end

2 对象的创建与使用

创建对象需要两步:分配内存初始化

// 1. 导入头文件
#import "Person.h"
// ...
// 2. 创建对象
Person *person1 = [[Person alloc] init];
// 3. 使用点语法或 setter 方法设置属性
person1.name = @"Alice";
person1.age = 30;
// 4. 调用方法
[person1 sayHello]; // 输出: Hello, my name is Alice and I'm 30 years old.
// 5. 使用类方法创建对象
Person *person2 = [Person personWithName:@"Bob" age:25];
[person2 sayHello]; // 输出: Hello, my name is Bob and I'm 25 years old.

3 消息传递**

这是 Objective-C 的核心思想。调用一个方法,在 Objective-C 中被称为“向对象发送一条消息”

语法格式:[接收者 消息]

  • [person1 sayHello]:向 person1 这个对象发送 sayHello 消息。
  • [Person personWithName:@"Bob" age:25]:向 Person 这个类发送 personWithName:age: 消息。

消息的接收者甚至可以响应一个它没有声明的方法(这被称为“消息转发”),这是其动态性的体现。

4 属性

@property 是 Objective-C 2.0 引入的语法糖,极大地简化了代码。

  • 生成成员变量:默认情况下,@property 会自动在 .m 文件的实现块中生成一个带下划线 _ 的私有成员变量(如 _name)。
  • 生成 getter/setter 方法:它会自动为你生成访问和修改属性的方法(即 getter 和 setter)。
  • 属性修饰符
    • 内存管理修饰符:
      • strong: 默认,对对象进行强引用,只要还有一个强引用指向它,对象就不会被销毁。
      • weak: 弱引用,不持有对象,对象被销毁后,指针会自动置为 nil,用于避免循环引用。
      • copy: 对赋值对象进行 copy 操作,常用于 NSString, NSArray 等不可变对象,防止其内容被意外修改。
      • assign: 用于基本数据类型(NSInteger, CGRect 等),是简单的值传递,不涉及内存管理。
      • retain: strong 的旧版写法,功能相同。
    • 原子性修饰符:
      • atomic (默认): 线程安全,但性能开销大,在 iOS 开发中几乎不用。
      • nonatomic: 非线程安全,性能高,是 iOS 开发的标准选择。

5 方法

  • 实例方法 ():作用于对象实例,必须先创建对象,然后用对象来调用。
    - (void)walk;
    - (NSString *)getFullName;
  • 类方法 ():作用于类本身,可以直接用类名调用,无需创建对象,常用于创建“工厂方法”或执行与类相关的操作。
    + (instancetype)defaultManager;
    + (void)initialize;
  • 方法名:Objective-C 的方法名由多个部分组成,每个冒号 都代表一个参数,这种命名方式非常具有描述性。
    // 这是一个方法名,它描述了整个操作
    - (void)setAge:(NSInteger)newAge;
    - (void)insertObject:(id)anObject atIndex:(NSUInteger)index;

6 协议

协议类似于 Java 中的接口或 C++ 中的纯虚类,它定义了一组方法,但不提供实现,任何类都可以采纳协议,并承诺实现这些方法。

协议定义 (.h 文件)

#import <Foundation/Foundation.h>
// @protocol 定义协议名
// @optional 表示方法可选,采纳协议的类可以选择性实现
// @required 表示方法必须实现(默认)
@protocol GreetingProtocol <NSObject>
@required
- (void)sayGreeting;
@optional
- (void)sayGoodbye;
@end

采纳协议

#import "GreetingProtocol.h"
@interface Dog : NSObject <GreetingProtocol>
@end
@implementation Dog
- (void)sayGreeting {
    NSLog(@"Woof! Hello!");
}
// sayGoodbye 是可选的,所以可以不实现
@end

协议是实现多态的关键,你可以定义一个方法,其参数类型是 id<GreetingProtocol>,然后传入任何采纳了该协议的对象。

7 分类

分类允许你为已存在的类添加方法,而无需修改其原始代码或创建子类,这对于扩展框架类(如 NSString)或给自定义类添加新功能非常有用。

语法原类名 + 分类名

示例:为 NSString 添加一个分类

  • 创建新文件,选择 "Objective-C File",File Type 选择 "Category",输入 Category Name 为 "Utils"。
  • 这会生成两个文件:NSString+Utils.hNSString+Utils.m

NSString+Utils.h

#import <Foundation/Foundation.h>
// 为 NSString 添加一个名为 Utils 的分类
@interface NSString (Utils)
- (BOOL)isNumeric;
@end

NSString+Utils.m

#import "NSString+Utils.h"
@implementation NSString (Utils)
- (BOOL)isNumeric {
    NSScanner *scanner = [NSScanner scannerWithString:self];
    float floatValue;
    return [scanner scanFloat:&floatValue] && [scanner isAtEnd];
}
@end

使用

NSString *numStr = @"123";
if ([numStr isNumeric]) {
    NSLog(@"'%@' is a number.", numStr);
}

8 块

块是 C 语言、Objective-C 和 Swift 中的闭包,它封装了一段代码和这段代码执行所需的状态(局部变量),它非常灵活,常用于异步操作、回调函数和集合遍历。

基本语法

^{
    // 封装的代码
    NSLog("This is a block.");
};
// 带参数和返回值的块
^(int a, int b) -> int {
    return a + b;
};

作为变量

// 定义一个块变量
void (^simpleBlock)(void) = ^{
    NSLog(@"Block as a variable.");
};
// 调用
simpleBlock();

在集合遍历中的使用

NSArray *names = @[@"Alice", @"Bob", @"Charlie"];
[names enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    NSLog(@"Index %lu: %@", (unsigned long)idx, obj);
    // 如果找到 "Bob",就停止遍历
    if ([obj isEqualToString:@"Bob"]) {
        *stop = YES;
    }
}];

内存管理

内存管理是 Objective-C 开发的核心难点之一,但现代的 ARC 已经极大地简化了它。

1 MRC (Manual Reference Counting) - 了解即可

在 ARC 出现之前,开发者需要手动管理内存,核心规则是:

  • alloc, new, copy, mutableCopy 会创建一个新对象,其引用计数为 1。
  • retain 会使引用计数加 1。
  • release 会使引用计数减 1。
  • 当引用计数为 0 时,对象会被自动销毁。
  • dealloc 方法在对象被销毁前调用,用于释放资源。

口诀:谁创建,谁释放;谁retain,谁release。

示例

// 错误示范:内存泄漏
NSString *str = [[NSString alloc] initWithFormat:@"Hello"];
// str 的引用计数为 1,但没有调用 release,它永远不会被释放
// 正确示范
NSString *str = [[NSString alloc] initWithFormat:@"Hello"];
[str release]; // 使用完后立即释放
// 使用 autorelease 延迟释放
NSString *str = [[[NSString alloc] initWithFormat:@"Hello"] autorelease];
// str 会在当前的 @autoreleasepool 结束时被释放

2 ARC (Automatic Reference Counting) - 现代 iOS 开发标准

Xcode 4.2 之后引入,编译器在编译时自动在代码中插入 retain, release, autorelease 调用,开发者无需手动管理。

核心规则

  1. 不再使用 retain, release, autorelease, dealloc(除了释放实例变量)
  2. 属性修饰符是关键strong, weak, copy, assign 的作用由编译器保证。
    • strong:相当于 MRC 中的 retain
    • weak:相当于 MRC 中的 assign,但用于对象,对象销毁时,weak 指针会自动置为 nil,有效避免了“野指针”问题。
  3. 循环引用:如果两个对象互相用 strong 引用对方,它们的引用计数永远无法归零,导致内存泄漏。解决方案是其中一端使用 weak

ARC 下的 dealloc 你仍然可以重写 dealloc 方法,但不能调用 [super dealloc],主要用于释放非 Objective-C 对象的资源,Core Foundation 对象。

@implementation MyView
- (void)dealloc {
    // 释放非 ARC 管理的资源
    CFRelease(_someCFObject);
    // 不要调用 [super dealloc];
}
@end

常用框架与工具

1 Foundation 框架

这是 Objective-C 的基石,提供了所有非图形化的基础类。

  • NSString / NSMutableString:不可变/可变字符串。
  • NSArray / NSMutableArray:不可变/可变对象数组。
  • NSDictionary / NSMutableDictionary:不可变/可变键值对字典。
  • NSSet / NSMutableSet:不可变/可变集合,保证元素唯一性。
  • NSNumber:将基本数据类型包装成对象。
  • NSData / NSMutableData:二进制数据。
  • NSDate / NSCalendar / NSDateFormatter:日期和时间处理。

2 Core Data

苹果官方的持久化框架,用于管理对象图,它不是一个数据库,而是一个对象图管理和持久化框架,它将对象模型映射到 SQLite 数据库文件中,让你可以用面向对象的方式操作数据。

3 Xcode 调试技巧

  • 断点:在代码行号左侧单击即可设置,程序运行到此处会暂停。
  • LLDB 控制台:断点暂停后,可以在控制台下命令,如 po (print object) 打印对象信息,p (print) 打印变量值。
  • 视图调试器:可以可视化地查看 App 的视图层级,方便定位 UI 问题。

学习路径与资源推荐

  1. 官方文档

  2. 经典书籍

    • 《Objective-C 编程》(又称“大黄书”):Objective-C 的“圣经”,内容详尽,适合系统学习。
    • 《Cocoa 编程》(又称“红宝书”):在掌握 Objective-C 后,学习 Cocoa 框架的必读之作。
  3. 在线资源

    • Ray Wenderlich:网站上有大量高质量的 iOS/macOS 开发教程,很多教程虽然使用 Swift,但其设计思想和架构模式同样适用于 Objective-C。
    • Stanford CS193P:斯坦福大学的 iOS 开发公开课,有历年视频和讲义,是入门的经典课程。
    • Stack Overflow:遇到具体问题时,这里是最好的求助社区。

为什么还要学 Objective-C?

尽管 Swift 是苹果的未来,但在当前和可预见的未来,学习 Objective-C 仍然至关重要:

  1. 维护现有代码:绝大多数成熟的 App、第三方库和开源项目都是用 Objective-C 写的,如果你想阅读、修改或贡献这些代码,就必须懂 Objective-C。
  2. 理解底层机制:Objective-C 的“裸露”特性(如运行时、消息传递)能让你更深刻地理解 iOS/macOS 系统的工作原理,学习 Swift 时,这些底层机制被隐藏了,而 Objective-C 让它们无处可藏。
  3. 特定领域的应用:一些底层性能要求极高的库或与 C 代码库交互紧密的场景,仍然会优先选择 Objective-C。
  4. 职业发展:在很多公司,尤其是那些有历史包袱的大型 App 团队,能够熟练阅读和修改 Objective-C 代码是一项重要的加分项。

学习建议:如果你是新手,可以直接从 Swift 开始,因为它更现代、更安全、更易学,当你对 iOS 开发有了基本了解后,再回头来学习 Objective-C,这时你会发现很多概念是相通的,学习起来会事半功倍,并能更好地理解整个苹果开发生态。

分享:
扫描分享到社交APP
上一篇
下一篇