杰瑞科技汇

objective-c 教程

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

目录

  1. 引言:什么是 Objective-C?
  2. 环境搭建
  3. 基础语法
    • 1 "Hello, World!"
    • 2 面向对象核心概念
    • 3 变量与数据类型
    • 4 方法
    • 5 属性
    • 6 内存管理 (MRC vs. ARC)
    • 7 协议 与代理
    • 8 类别
    • 9 块
  4. 实战项目:一个简单的待办事项 应用
  5. 学习资源与进阶

引言:什么是 Objective-C?

Objective-C 是一种通用的、面向对象的编程语言,它是 C 语言的超集,这意味着任何合法的 C 代码也是合法的 Objective-C 代码,它被广泛用于 Apple 的 macOS 和 iOS 操作系统的开发,是构建原生 Apple 应用程序的传统语言。

objective-c 教程-图1
(图片来源网络,侵删)

主要特点:

  • C 语言基础:拥有 C 语言的全部特性,包括指针、手动内存管理(早期)等。
  • Smalltalk 消息传递:其面向对象的特性深受 Smalltalk 影响,调用方法被称为“发送消息”,这使得它非常灵活和动态。
  • 运行时系统:Objective-C 的许多强大功能(如动态类型、方法交换)都是在运行时决定的,而不是编译时。
  • 与 Swift 共存:Apple 推荐使用 Swift 作为主要开发语言,但 Objective-C 仍然被广泛用于维护旧项目、与 C/C++ 库交互以及利用其成熟的生态。

环境搭建

学习 Objective-C 最主要的方式是使用 Apple 的官方集成开发环境。

  • 工具Xcode
  • 下载:从 Mac App Store 免费下载,Xcode 不仅包含编译器,还包含了 Interface Builder(用于可视化界面设计)、模拟器、调试器等全套工具。
  • 创建新项目
    1. 打开 Xcode,选择 "Create a new Xcode project"。
    2. 选择 "macOS" -> "Command Line Tool" 或 "iOS" -> "App"。
    3. 语言选择 Objective-C

基础语法

1 "Hello, World!"

创建一个 Command Line Tool 项目后,你会看到一个 main.m 文件。

// main.m
#import <Foundation/Foundation.h> // 导入 Foundation 框架,包含了基本的数据类型和工具
int main(int argc, const char * argv[]) {
    @autoreleasepool { // 自动释放池,用于管理内存(ARC 环境下必需)
        // NSLog 是 Foundation 框架提供的日志输出函数,类似于 C 的 printf
        // 它会自动在输出后添加换行符和时间戳等信息
        NSLog(@"Hello, World!");
    }
    return 0;
}

关键点

objective-c 教程-图2
(图片来源网络,侵删)
  • #import:类似于 C 的 #include,但会防止同一个文件被重复导入。
  • <Foundation/Foundation.h>:是 Objective-C 的核心框架,包含了字符串、数组、字典等基本类。
  • @autoreleasepool:在 ARC(自动引用计数)环境下,用于创建一个作用域,当作用域结束时,其中的自动释放对象会被释放。
  • 这是 Objective-C 的字符串字面量,属于 NSString 对象。
  • NSLog:格式化输出字符串, 是一个格式说明符,用于打印对象。

2 面向对象核心概念

Objective-C 中的两个核心结构是 接口实现

  • 接口:定义了类的公共行为(方法)和属性,通常以 .h (header) 文件结尾。
  • 实现:定义了接口中声明的具体代码逻辑,通常以 .m (implementation) 文件结尾。

一个简单的 Car 类示例:

Car.h (接口文件)

#import <Foundation/Foundation.h>
// @interface 声明一个类
// 继承自 NSObject,所有 Objective-C 类的根类
@interface Car : NSObject
// 声明一个属性
// @property 自动生成 getter 和 setter 方法
// nonatomic: 非原子操作,性能更高
// strong: 强引用,表示对对象的所有权
@property (nonatomic, strong) NSString *brand;
// 声明一个方法
// - 表示实例方法 (需要对象才能调用)
// (void) 表示返回类型是 void
// (NSString *) 表示返回类型是 NSString 对象
- (void)drive;
- (NSString *)getBrand;
@end

Car.m (实现文件)

objective-c 教程-图3
(图片来源网络,侵删)
#import "Car.h" // 导入自己的头文件
// @implementation 实现一个类
@implementation Car
// @synthesize 让编译器自动生成 brand 属性的 getter/setter 方法
// (在较新版本的 Xcode 中,可以省略 @synthesize,编译器会自动完成)
@synthesize brand;
// 实现 drive 方法
- (void)drive {
    NSLog(@"The %@ car is driving.", self.brand);
}
// 实现 getBrand 方法
- (NSString *)getBrand {
    return self.brand;
}
@end

3 变量与数据类型

  • 基本数据类型:和 C 语言一样,int, float, double, char, BOOL (YES/NO)。
  • 对象类型:使用指针来表示,NSString *, NSArray *, Car *
  • id 类型:一个万能的对象类型,可以指向任何 Objective-C 对象,非常灵活,但会失去编译时类型检查。
NSString *name = @"John"; // 字符串对象
int age = 30;
BOOL isStudent = NO;
id someObject = @"I can be anything"; // 合法
someObject = @123; // 也合法

4 方法

Objective-C 的方法声明和调用非常独特。

方法签名格式-/+ (返回类型) 方法名: (参数类型)参数名1 参数名2: (参数类型)参数名2 ...

  • (实例方法) / (类方法,类似静态方法)
  • 是参数的分割符,参数名也参与方法签名。

示例:

声明

- (void)setModel:(NSString *)model andYear:(int)year;
+ (instancetype)carWithBrand:(NSString *)brand; // 工厂类方法

调用

Car *myCar = [[Car alloc] init]; // 创建对象
[myCar setModel:@"Model S" andYear:2025]; // 调用实例方法
Car *tesla = [Car carWithBrand:@"Tesla"]; // 调用类方法

5 属性

@property 是一个编译器指令,可以自动为实例变量生成 getter 和 setter 方法。

属性修饰符

  • 原子性:
    • atomic (默认): 线程安全,但性能开销大。
    • nonatomic: 非线程安全,性能高,在 iOS 开发中几乎总是使用 nonatomic
  • 引用/所有权:
    • strong: 强引用,持有对象,对象会一直存在,直到没有强引用指向它,用于对象类型。
    • weak: 弱引用,不持有对象,对象被销毁时,指针会自动置为 nil,用于避免循环引用(如 delegate)。
    • assign: 用于基本数据类型 (int, BOOL 等),或用于解决循环引用的特殊情况。
    • copy: 创建一个副本,用于可变对象(如 NSMutableString),防止外部修改影响内部。

示例

@property (nonatomic, strong) NSMutableString *name; // 使用 strong
@property (nonatomic, weak) id delegate; // 使用 weak
@property (nonatomic, assign) NSInteger age; // 使用 assign

6 内存管理

这是 Objective-C 中一个至关重要的主题。

  • MRC (Manual Reference Counting):手动管理,程序员需要手动调用 retain, release, autorelease 来增加和减少引用计数,当计数为 0 时,对象被销毁。(现已不推荐,但了解历史很重要)
  • ARC (Automatic Reference Counting):自动引用计数,Xcode 编译器会在编译时自动插入 retain, release 等代码,极大地简化了内存管理。(现代 Objective-C 开发的标准)

ARC 规则

  • 你仍然需要理解 strong, weak, assign 的区别。
  • 不能调用 retain, release, autorelease, dealloc 等方法(除了在 dealloc 中释放非对象资源)。
  • @autoreleasepool 块仍然需要用于管理大量临时创建的对象。

dealloc 方法: 当一个对象即将被销毁时,系统会调用其 dealloc 方法,你需要手动释放那些不属于 ARC 管理的资源(你通过 malloc 分配的 C 语言内存)。

@implementation MyClass {
    void *someCFObject; // 假设这是一个 Core Foundation 对象
}
- (void)dealloc {
    CFRelease(someCFObject); // 手动释放
    [super dealloc]; // MRC 需要调用,ARC 会自动处理,不应手动调用
}
@end

7 协议 与代理

协议定义了一组方法,但不提供实现,任何类都可以遵循一个协议,并实现其方法,这是实现委托模式的基础。

协议示例 (CarProtocol.h)**

#import <Foundation/Foundation.h>
// @protocol 定义一个协议
// @optional 表示遵循协议的类可以选择性实现的方法
// @required (默认) 表示必须实现的方法
@protocol CarProtocol <NSObject>
@required
- (void)carDidStartEngine:(Car *)car;
@optional
- (void)carDidStopEngine:(Car *)car;
@end

在类中使用协议

// 在 .h 文件中
#import "CarProtocol.h"
@interface Car : NSObject
@property (nonatomic, weak) id<CarProtocol> delegate; // delegate 必须遵循 CarProtocol
- (void)startEngine;
@end
// 在 .m 文件中
@implementation Car
- (void)startEngine {
    NSLog(@"Engine started.");
    // 检查 delegate 是否存在并是否响应这个方法
    if ([self.delegate respondsToSelector:@selector(carDidStartEngine:)]) {
        [self.delegate carDidStartEngine:self];
    }
}
@end

8 类别

允许你在不修改原类源代码的情况下,为已存在的类添加新方法,非常实用。

示例:为 NSString 添加一个 MD5 哈希方法

// NSString+MD5.h
#import <Foundation/Foundation.h>
@interface NSString (MD5)
- (NSString *)md5Hash;
@end
// NSString+MD5.m
#import "NSString+MD5.h"
#import <CommonCrypto/CommonDigest.h> // Apple 的加密框架
@implementation NSString (MD5)
- (NSString *)md5Hash {
    const char *str = [self UTF8String];
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5(str, (CC_LONG)strlen(str), result);
    NSMutableString *ret = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        [ret appendFormat:@"%02x", result[i]];
    }
    return ret;
}
@end

使用方式:

NSString *myString = @"hello";
NSString *hash = [myString md5Hash];
NSLog(@"%@", hash); // 输出 5d41402abc4b2a76b9719d911017c592

9 块

Block 是 C 语言、Objective-C 和 Swift 中的一个强大特性,它是一种匿名函数,可以捕获其所在作用域的变量。

语法^ (插入符号) 是 Block 的标志。

// 定义一个 Block 变量
int (^myBlock)(int, int) = ^(int a, int b) {
    return a + b;
};
// 调用 Block
int result = myBlock(5, 3);
NSLog(@"Result: %d", result); // 输出 Result: 8
// 常用于作为方法的参数,例如数组的排序
NSArray *strings = @"hello world from objective-c".componentsSeparatedByString:@" ";
NSLog(@"Sorted: %@", [strings sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    return [obj1 compare:obj2]; // 按字母顺序排序
}]);

实战项目:一个简单的待办事项 应用

这个项目将涵盖创建 UI、处理用户输入、数据存储和委托模式。

目标:一个可以添加、显示待办事项的应用。

步骤

  1. 创建项目:在 Xcode 中创建一个新的 Single View App 项目,语言选择 Objective-C。
  2. 设计界面
    • 打开 Main.storyboard
    • 添加一个 UITableView 用于显示待办事项列表。
    • 添加一个 UITextField 用于输入新事项。
    • 添加一个 UIButton 用于添加事项。
    • 使用 Auto Layout 约束好它们的位置。
  3. 创建数据模型
    • 新建一个 TodoItem 类,只有一个 title 属性。
  4. 连接 UI 与代码
    • 打开 ViewController.h,为 UITableView, UITextField, UIButton 创建 @property (并连接到 Storyboard 中的控件)。
    • 遵循 UITableViewDataSourceUITableViewDelegate 协议。
  5. 实现数据源方法
    • ViewController.m 中实现 tableView:numberOfRowsInSection:tableView:cellForRowAtIndexPath: 方法来显示列表。
  6. 处理添加逻辑
    • 为 "Add" 按钮创建一个 IBAction
    • 在方法中,获取 UITextField 的文本,创建一个新的 TodoItem 对象,并添加到一个数组中。
    • 刷新 UITableView ([self.tableView reloadData];)。
  7. 持久化存储 (使用 NSUserDefaults)
    • viewDidLoad 中,从 UserDefaults 读取已保存的待办事项列表。
    • 在添加新事项或应用将要退出时,将列表保存到 UserDefaults

这是一个简化的流程,但足以让你了解如何将所学知识组合起来构建一个完整的应用。


学习资源与进阶

  • 官方文档
  • 书籍
    • 《Objective-C 编程》:Aaron Hillegass 著,Big Nerd Ranch 系列书籍,讲解清晰,实例丰富。
    • 《Cocoa 编程》:Aaron Hillegass 著,在掌握 Objective-C 后阅读,深入讲解 macOS/iOS 的框架。
  • 在线教程
    • Ray Wenderlich:网站上有大量高质量的 Objective-C 和 Swift 教程。
    • 斯坦福大学公开课:CS193P (iOS) 和 CS193M (macOS) 的早期课程是基于 Objective-C 的,是绝佳的学习材料。
  • 进阶主题
    • Core Data:Apple 的官方数据持久化框架。
    • Core Animation:用于创建流畅的动画效果。
    • 网络编程:使用 NSURLSession 进行网络请求。
    • 与 C++ 交互:了解如何混合使用 Objective-C 和 C++(称为 "Objective-C++")。

希望这份教程能帮助你顺利入门 Objective-C!虽然 Swift 是现在的趋势,但掌握 Objective-C 能让你更好地理解 Apple 生态的底层,并能维护庞大的现有代码库。

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