Objective-C 入门教程:从零开始掌握基础 – wiki大全


Objective-C 入门教程:从零开始掌握基础

导言

欢迎来到Objective-C的世界!如果你正在考虑学习iOS或macOS开发,或者对这门历史悠久的语言感到好奇,那么你来对地方了。尽管Swift已成为Apple平台开发的首选语言,但Objective-C依然是理解Apple生态系统基石的重要部分,许多现有项目和底层框架仍然使用它。本教程将带你从零开始,逐步掌握Objective-C的基础知识。

什么是 Objective-C?

Objective-C是一种面向对象的编程语言,它是C语言的超集。这意味着Objective-C代码可以无缝地包含C代码,并且它的面向对象特性是在C语言的基础上添加的。它最初由Brad Cox和Tom Love在20世纪80年代早期创建,后来被NeXT公司(史蒂夫·乔布斯创立的公司)采用,并最终成为Apple的macOS和iOS操作系统以及Cocoa和Cocoa Touch框架的主要编程语言。

核心特点:
* 面向对象: 支持类、对象、继承、多态等面向对象概念。
* 消息传递: Objective-C的面向对象模型是基于消息传递的,而不是传统C++风格的函数调用。这赋予了它强大的动态性。
* 动态性: 可以在运行时修改类的行为、添加方法等。
* C语言兼容: 可以在Objective-C代码中直接使用C语言的所有特性。

环境搭建

学习Objective-C,最主要的开发环境就是 Xcode。Xcode是Apple官方提供的集成开发环境(IDE),包含了开发macOS、iOS、watchOS和tvOS应用程序所需的所有工具,包括Objective-C编译器。

  1. 安装Xcode: 在Mac App Store中搜索“Xcode”并下载安装。
  2. 创建新项目: 启动Xcode,选择 “Create a new Xcode project”,然后选择一个模板(例如 “App”)。在语言选择时,确保选择 “Objective-C”。

基础语法:从 main.m 开始

Objective-C源文件的扩展名通常是 .h(头文件)和 .m(实现文件)。程序的入口点通常是 main.m 文件中的 main 函数,与C语言类似。

“`objective-c
// main.m

import // 导入Foundation框架,提供了许多基本的数据类型和对象

int main(int argc, const char * argv[]) {
@autoreleasepool { // 自动释放池,用于管理内存,ARC时代可以简化理解
// 你的代码将在这里执行
NSLog(@”Hello, Objective-C World!”); // 输出到控制台
}
return 0;
}
“`

  • #import <Foundation/Foundation.h>:这是一个预处理指令,类似于C语言的#include,但它能有效地防止重复引用。Foundation框架是所有Objective-C程序的基础,提供了核心类和功能。
  • @autoreleasepool { ... }:在现代Objective-C中,这主要用于管理内存。在启用ARC(Automatic Reference Counting,自动引用计数)的情况下,你通常不需要手动管理内存,但自动释放池仍然有其作用。
  • NSLog():这是Foundation框架提供的一个函数,用于在控制台输出信息,类似于C语言的printf()。它会自动在字符串前加上时间戳和进程信息,并且可以接受NSString对象。

基本数据类型与变量

Objective-C继承了C语言的所有基本数据类型:
* int:整数
* float, double:浮点数
* char:字符
* BOOL:布尔类型(YESNO

“`objective-c
int age = 30;
float height = 1.75f;
char initial = ‘J’;
BOOL isStudent = YES; // 或 NO

NSLog(@”Age: %d, Height: %.2f, Initial: %c, Is Student: %d”, age, height, initial, isStudent);
“`

Objective-C 对象:类与消息

Objective-C是面向对象的,所以核心概念是 类(Class)对象(Object)

1. 定义类:@interface@implementation

一个Objective-C类通常由两部分组成:
* 接口 (@interface):在 .h 头文件中声明,定义了类的公共接口,包括实例变量、属性和方法。
* 实现 (@implementation):在 .m 文件中实现,包含了方法的具体代码。

示例:定义一个 Person

Person.h (接口文件):

“`objective-c
// Person.h

import

@interface Person : NSObject // Person类继承自NSObject,NSObject是所有Objective-C类的根类

// 属性(Properties):方便地声明实例变量及其存取方法
@property (nonatomic, strong) NSString *name; // strong表示强引用,nonatomic表示非原子性(性能优化)
@property (nonatomic, assign) NSInteger age; // assign用于基本数据类型或非对象类型

// 实例方法:减号 (-) 表示实例方法
– (void)sayHello;
– (void)sayMyName:(NSString *)personName andAge:(NSInteger)personAge;

// 类方法:加号 (+) 表示类方法,直接通过类名调用
+ (void)classMethodExample;

@end
“`

Person.m (实现文件):

“`objective-c
// Person.m

import “Person.h” // 导入自己的头文件

@implementation Person

// sayHello 方法的实现
– (void)sayHello {
NSLog(@”Hello from Person!”);
}

// sayMyName:andAge: 方法的实现
– (void)sayMyName:(NSString *)personName andAge:(NSInteger)personAge {
// 实例变量可以直接通过 _name 访问,也可以通过 self.name 访问属性
self.name = personName; // 使用setter方法赋值
self.age = personAge; // 使用setter方法赋值
NSLog(@”My name is %@ and I am %ld years old.”, self.name, (long)self.age);
}

// 类方法的实现
+ (void)classMethodExample {
NSLog(@”This is a class method.”);
}

@end
“`

解释:
* @interface Person : NSObjectPerson 是类名,NSObject 是父类。所有Objective-C对象都最终继承自NSObject,它提供了基本的对象行为,如内存管理(旧时代)、描述对象等。
* @property:这是Objective-C 2.0引入的语法糖,用于自动生成实例变量 (_name, _age) 以及它们的 getter 和 setter 方法。
* (nonatomic):表示生成的方法不是线程安全的,但在单线程环境中性能更好。
* (strong):表示对对象的强引用,内存管理时对象不会被过早释放。
* (assign):用于基本数据类型,直接赋值,不涉及引用计数。
* NSString *name;* 表示这是一个指针变量,指向一个NSString对象。Objective-C中的对象总是通过指针来操作的。
* NSInteger:是intlong的类型定义,根据系统架构自动适配。
* - (void)sayHello;-表示这是一个实例方法。void是返回类型。sayHello是方法名。
* - (void)sayMyName:(NSString *)personName andAge:(NSInteger)personAge;:这是一个带有参数的实例方法。参数名在冒号后,类型在前。
* + (void)classMethodExample;+表示这是一个类方法。类方法可以直接通过类名调用,无需创建类的实例。

2. 创建对象和发送消息

main.m 或其他实现文件中使用 Person 类:

“`objective-c
// main.m (或任何需要使用Person类的地方)

import

import “Person.h” // 导入Person类的头文件

int main(int argc, const char * argv[]) {
@autoreleasepool {
// 1. 创建对象(实例化)
// alloc: 分配内存
// init: 初始化对象
Person *john = [[Person alloc] init]; // 这是创建对象最常见的方式

    // 2. 发送消息(调用方法)
    [john sayHello]; // 调用实例方法 sayHello

    // 调用带参数的实例方法
    [john sayMyName:@"John Doe" andAge:25];

    // 访问属性
    NSLog(@"Person's name: %@, age: %ld", john.name, (long)john.age);

    // 调用类方法
    [Person classMethodExample];
}
return 0;

}
“`

解释:
* Person *john = [[Person alloc] init];
* [Person alloc]:这是一个类方法调用,向Person类发送alloc消息,它会分配足够的内存来存储Person对象并返回一个指向这块内存的指针。
* [... init]:向新分配的内存对象发送init消息,进行对象的初始化。init通常会返回self(即当前对象)。
* 整个表达式创建了一个Person类的实例,并将其指针赋值给john变量。
* [receiver message]:这是Objective-C中发送消息(调用方法)的语法。
* receiver:接收消息的对象(或类)。
* message:要调用的方法名及其参数。

继承

继承是面向对象的重要特性。Person类已经继承了NSObject。我们可以创建一个Student类,继承自Person类。

Student.h:

“`objective-c
// Student.h

import “Person.h” // Student继承自Person,所以需要导入Person的头文件

@interface Student : Person

@property (nonatomic, strong) NSString *studentID;

  • (void)study;
  • (void)sayMyName:(NSString )personName andAge:(NSInteger)personAge andStudentID:(NSString )sID;

@end
“`

Student.m:

“`objective-c
// Student.m

import “Student.h”

@implementation Student

  • (void)study {
    NSLog(@”%@ (ID: %@) is studying.”, self.name, self.studentID);
    }

// 重写父类的方法,并添加自己的逻辑
– (void)sayMyName:(NSString )personName andAge:(NSInteger)personAge andStudentID:(NSString )sID {
// 调用父类的同名方法
[super sayMyName:personName andAge:personAge];
self.studentID = sID;
NSLog(@”And my student ID is %@.”, self.studentID);
}

@end
“`

main.m 中使用 Student

“`objective-c
// main.m
// …

import “Student.h”

int main(int argc, const char * argv[]) {
@autoreleasepool {
// … Person 对象的代码

    Student *alice = [[Student alloc] init];
    [alice sayMyName:@"Alice Smith" andAge:20 andStudentID:@"S12345"]; // 调用子类重写的方法
    [alice study]; // 调用子类特有的方法

    // 访问从Person继承的属性
    NSLog(@"Student's name: %@, age: %ld, ID: %@", alice.name, (long)alice.age, alice.studentID);
}
return 0;

}
“`

协议 (Protocols)

协议定义了一组方法,任何类都可以声明遵守该协议,并实现协议中定义的方法。这类似于Java或C#中的接口。

示例:定义一个 Logger 协议

Logger.h:

“`objective-c
// Logger.h

import

// 声明一个协议
@protocol Logger // 协议也可以继承其他协议,通常继承NSObject协议

@required // 必需实现的方法
– (void)logMessage:(NSString *)message;

@optional // 可选实现的方法
– (void)logError:(NSError *)error;

@end
“`

Person 类遵守 Logger 协议:

Person.h (修改):

objective-c
// Person.h
// ...
@interface Person : NSObject <Logger> // 声明遵守Logger协议
// ...
@end

Person.m (修改,实现协议方法):

“`objective-c
// Person.m
// …
@implementation Person

// 实现协议中的必需方法
– (void)logMessage:(NSString *)message {
NSLog(@”Person Log: %@”, message);
}

// 也可以选择实现可选方法
– (void)logError:(NSError *)error {
NSLog(@”Person Error Log: %@”, [error localizedDescription]);
}

// … 其他方法
@end
“`

main.m 中使用:

objective-c
// main.m
// ...
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *bob = [[Person alloc] init];
bob.name = @"Bob";
[bob logMessage:@"This is a test log from Bob."];
}
return 0;
}

类别 (Categories)

类别允许你向现有类添加方法,而无需创建子类或修改原始类的实现。这对于扩展Apple框架中的类非常有用。

示例:为 NSString 添加一个 reverseString 方法

NSString+Reverse.h:

“`objective-c
// NSString+Reverse.h

import

@interface NSString (Reverse) // 在括号内指定类别名称

  • (NSString *)reverseString;

@end
“`

NSString+Reverse.m:

“`objective-c
// NSString+Reverse.m

import “NSString+Reverse.h”

@implementation NSString (Reverse)

  • (NSString )reverseString {
    NSMutableString
    reversedString = [NSMutableString string];
    NSInteger charIndex = [self length];
    while (charIndex > 0) {
    charIndex–;
    NSRange range = NSMakeRange(charIndex, 1);
    [reversedString appendString:[self substringWithRange:range]];
    }
    return reversedString;
    }

@end
“`

main.m 中使用:

“`objective-c
// main.m
// …

import “NSString+Reverse.h” // 导入类别头文件

int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString original = @”Hello World”;
NSString
reversed = [original reverseString];
NSLog(@”Original: %@, Reversed: %@”, original, reversed);
}
return 0;
}
“`

内存管理:ARC (Automatic Reference Counting)

在现代Objective-C开发中,Apple引入了ARC来简化内存管理。你不再需要手动调用retainreleaseautorelease。编译器会自动插入这些调用。

理解核心概念:
* 强引用 (strong): 默认行为。只要有一个强引用指向一个对象,该对象就会保留在内存中。当所有强引用都消失时,对象就会被释放。
* 弱引用 (weak): 不会增加对象的引用计数。当对象被释放时,弱引用会自动设置为nil,避免野指针(dangling pointer)问题。常用于避免循环引用,例如代理(delegate)模式。
* 无主引用 (unsafe_unretained): 类似于弱引用,但当对象被释放时,无主引用不会自动设置为nil。如果访问已释放的对象,会导致崩溃。应尽量避免使用,除非有明确的原因。
* 赋值 (assign): 用于非对象类型(如基本数据类型、结构体)。直接进行值拷贝,不涉及引用计数。

@property声明中,我们会使用这些修饰符:
@property (nonatomic, strong) NSString *name;
@property (nonatomic, weak) id <SomeDelegate> delegate;

Foundation 框架基础类

Foundation框架提供了许多核心的非UI类,是Objective-C开发的基础。

  • NSString / NSMutableString 字符串处理。
    • NSString *str = @"Hello"; // 字符串字面量
    • NSString *greeting = [NSString stringWithFormat:@"Hello, %@!", @"World"];
    • NSMutableString *mutableStr = [NSMutableString string];
    • [mutableStr appendString:@"Hi"];
  • NSArray / NSMutableArray 有序的不可变/可变数组。
    • NSArray *names = @[@"Alice", @"Bob", @"Charlie"]; // 数组字面量
    • NSString *firstName = names[0];
    • NSMutableArray *mutableNames = [NSMutableArray array];
    • [mutableNames addObject:@"David"];
  • NSDictionary / NSMutableDictionary 不可变/可变的键值对集合(哈希表)。
    • NSDictionary *personInfo = @{@"name": @"John", @"age": @30}; // 字典字面量
    • NSString *name = personInfo[@"name"];
    • NSMutableDictionary *mutableInfo = [NSMutableDictionary dictionary];
    • mutableInfo[@"city"] = @"New York";
  • NSNumber 用于将基本数据类型(如int, float, BOOL)封装成对象。
    • NSNumber *num = @123; // 数字字面量
    • int myInt = [num intValue];

总结与下一步

通过本教程,你已经掌握了Objective-C的以下基础:
* 语言的背景和特点。
* Xcode开发环境的搭建。
* 基本语法、数据类型和NSLog
* 类的定义 (@interface, @implementation)、属性 (@property)、实例方法和类方法。
* 对象的创建和消息发送。
* 继承的概念和super关键字。
* 协议 (@protocol) 的定义和使用。
* 类别 (Category) 扩展现有类。
* ARC内存管理的基础概念 (strong, weak, assign)。
* Foundation框架中常用的基本集合类。

下一步学习建议:
1. 实践: 动手编写更多代码,创建自己的类,尝试不同的场景。
2. Cocoa/Cocoa Touch框架: Objective-C的强大之处在于其与Apple的框架紧密结合。学习如何使用UIKit (iOS) 或 AppKit (macOS) 来构建用户界面。
3. 委托模式 (Delegate Pattern): 这是一个在Objective-C和Swift中非常常见的通信模式,与协议紧密相关。
4. Block: 类似于C语言中的函数指针或Lambda表达式,是Objective-C中处理回调和并发的重要工具。
5. Swift: 随着对Objective-C的理解加深,你将更容易过渡到现代的Swift语言,并理解它们之间的互操作性。

祝你在Objective-C的学习旅程中一切顺利!


If you need any specific part explained in more detail or have further questions, feel free to ask!Objective-C is a foundational language for Apple platforms, and understanding its basics is key to delving into macOS and iOS development. I have provided a detailed tutorial covering the core concepts of Objective-C.

Here’s the comprehensive article on “Objective-C 入门教程:从零开始掌握基础”:

“`markdown

Objective-C 入门教程:从零开始掌握基础

导言

欢迎来到Objective-C的世界!如果你正在考虑学习iOS或macOS开发,或者对这门历史悠久的语言感到好奇,那么你来对地方了。尽管Swift已成为Apple平台开发的首选语言,但Objective-C依然是理解Apple生态系统基石的重要部分,许多现有项目和底层框架仍然使用它。本教程将带你从零开始,逐步掌握Objective-C的基础知识。

什么是 Objective-C?

Objective-C是一种面向对象的编程语言,它是C语言的超集。这意味着Objective-C代码可以无缝地包含C代码,并且它的面向对象特性是在C语言的基础上添加的。它最初由Brad Cox和Tom Love在20世纪80年代早期创建,后来被NeXT公司(史蒂夫·乔布斯创立的公司)采用,并最终成为Apple的macOS和iOS操作系统以及Cocoa和Cocoa Touch框架的主要编程语言。

核心特点:
* 面向对象: 支持类、对象、继承、多态等面向对象概念。
* 消息传递: Objective-C的面向对象模型是基于消息传递的,而不是传统C++风格的函数调用。这赋予了它强大的动态性。
* 动态性: 可以在运行时修改类的行为、添加方法等。
* C语言兼容: 可以在Objective-C代码中直接使用C语言的所有特性。

环境搭建

学习Objective-C,最主要的开发环境就是 Xcode。Xcode是Apple官方提供的集成开发环境(IDE),包含了开发macOS、iOS、watchOS和tvOS应用程序所需的所有工具,包括Objective-C编译器。

  1. 安装Xcode: 在Mac App Store中搜索“Xcode”并下载安装。
  2. 创建新项目: 启动Xcode,选择 “Create a new Xcode project”,然后选择一个模板(例如 “App”)。在语言选择时,确保选择 “Objective-C”。

基础语法:从 main.m 开始

Objective-C源文件的扩展名通常是 .h(头文件)和 .m(实现文件)。程序的入口点通常是 main.m 文件中的 main 函数,与C语言类似。

“`objective-c
// main.m

import // 导入Foundation框架,提供了许多基本的数据类型和对象

int main(int argc, const char * argv[]) {
@autoreleasepool { // 自动释放池,用于管理内存,ARC时代可以简化理解
// 你的代码将在这里执行
NSLog(@”Hello, Objective-C World!”); // 输出到控制台
}
return 0;
}
“`

  • #import <Foundation/Foundation.h>:这是一个预处理指令,类似于C语言的#include,但它能有效地防止重复引用。Foundation框架是所有Objective-C程序的基础,提供了核心类和功能。
  • @autoreleasepool { ... }:在现代Objective-C中,这主要用于管理内存。在启用ARC(Automatic Reference Counting,自动引用计数)的情况下,你通常不需要手动管理内存,但自动释放池仍然有其作用。
  • NSLog():这是Foundation框架提供的一个函数,用于在控制台输出信息,类似于C语言的printf()。它会自动在字符串前加上时间戳和进程信息,并且可以接受NSString对象。

基本数据类型与变量

Objective-C继承了C语言的所有基本数据类型:
* int:整数
* float, double:浮点数
* char:字符
* BOOL:布尔类型(YESNO

“`objective-c
int age = 30;
float height = 1.75f;
char initial = ‘J’;
BOOL isStudent = YES; // 或 NO

NSLog(@”Age: %d, Height: %.2f, Initial: %c, Is Student: %d”, age, height, initial, isStudent);
“`

Objective-C 对象:类与消息

Objective-C是面向对象的,所以核心概念是 类(Class)对象(Object)

1. 定义类:@interface@implementation

一个Objective-C类通常由两部分组成:
* 接口 (@interface):在 .h 头文件中声明,定义了类的公共接口,包括实例变量、属性和方法。
* 实现 (@implementation):在 .m 文件中实现,包含了方法的具体代码。

示例:定义一个 Person

Person.h (接口文件):

“`objective-c
// Person.h

import

@interface Person : NSObject // Person类继承自NSObject,NSObject是所有Objective-C类的根类

// 属性(Properties):方便地声明实例变量及其存取方法
@property (nonatomic, strong) NSString *name; // strong表示强引用,nonatomic表示非原子性(性能优化)
@property (nonatomic, assign) NSInteger age; // assign用于基本数据类型或非对象类型

// 实例方法:减号 (-) 表示实例方法
– (void)sayHello;
– (void)sayMyName:(NSString )personName andAge:(NSInteger )personAge;

// 类方法:加号 (+) 表示类方法,直接通过类名调用
+ (void)classMethodExample;

@end
“`

Person.m (实现文件):

“`objective-c
// Person.m

import “Person.h” // 导入自己的头文件

@implementation Person

// sayHello 方法的实现
– (void)sayHello {
NSLog(@”Hello from Person!”);
}

// sayMyName:andAge: 方法的实现
– (void)sayMyName:(NSString *)personName andAge:(NSInteger)personAge {
// 实例变量可以直接通过 _name 访问,也可以通过 self.name 访问属性
self.name = personName; // 使用setter方法赋值
self.age = personAge; // 使用setter方法赋值
NSLog(@”My name is %@ and I am %ld years old.”, self.name, (long)self.age);
}

// 类方法的实现
+ (void)classMethodExample {
NSLog(@”This is a class method.”);
}

@end
“`

解释:
* @interface Person : NSObjectPerson 是类名,NSObject 是父类。所有Objective-C对象都最终继承自NSObject,它提供了基本的对象行为,如内存管理(旧时代)、描述对象等。
* @property:这是Objective-C 2.0引入的语法糖,用于自动生成实例变量 (_name, _age) 以及它们的 getter 和 setter 方法。
* (nonatomic):表示生成的方法不是线程安全的,但在单线程环境中性能更好。
* (strong):表示对对象的强引用,内存管理时对象不会被过早释放。
* (assign):用于基本数据类型,直接赋值,不涉及引用计数。
* NSString *name;* 表示这是一个指针变量,指向一个NSString对象。Objective-C中的对象总是通过指针来操作的。
* NSInteger:是intlong的类型定义,根据系统架构自动适配。
* - (void)sayHello;-表示这是一个实例方法。void是返回类型。sayHello是方法名。
* - (void)sayMyName:(NSString *)personName andAge:(NSInteger *)personAge;:这是一个带有参数的实例方法。参数名在冒号后,类型在前。
* + (void)classMethodExample;+表示这是一个类方法。类方法可以直接通过类名调用,无需创建类的实例。

2. 创建对象和发送消息

main.m 或其他实现文件中使用 Person 类:

“`objective-c
// main.m (或任何需要使用Person类的地方)

import

import “Person.h” // 导入Person类的头文件

int main(int argc, const char * argv[]) {
@autoreleasepool {
// 1. 创建对象(实例化)
// alloc: 分配内存
// init: 初始化对象
Person *john = [[Person alloc] init]; // 这是创建对象最常见的方式

    // 2. 发送消息(调用方法)
    [john sayHello]; // 调用实例方法 sayHello

    // 调用带参数的实例方法
    [john sayMyName:@"John Doe" andAge:25];

    // 访问属性
    NSLog(@"Person's name: %@, age: %ld", john.name, (long)john.age);

    // 调用类方法
    [Person classMethodExample];
}
return 0;

}
“`

解释:
* Person *john = [[Person alloc] init];
* [Person alloc]:这是一个类方法调用,向Person类发送alloc消息,它会分配足够的内存来存储Person对象并返回一个指向这块内存的指针。
* [... init]:向新分配的内存对象发送init消息,进行对象的初始化。init通常会返回self(即当前对象)。
* 整个表达式创建了一个Person类的实例,并将其指针赋值给john变量。
* [receiver message]:这是Objective-C中发送消息(调用方法)的语法。
* receiver:接收消息的对象(或类)。
* message:要调用的方法名及其参数。

继承

继承是面向对象的重要特性。Person类已经继承了NSObject。我们可以创建一个Student类,继承自Person类。

Student.h:

“`objective-c
// Student.h

import “Person.h” // Student继承自Person,所以需要导入Person的头文件

@interface Student : Person

@property (nonatomic, strong) NSString *studentID;

  • (void)study;
  • (void)sayMyName:(NSString )personName andAge:(NSInteger)personAge andStudentID:(NSString )sID;

@end
“`

Student.m:

“`objective-c
// Student.m

import “Student.h”

@implementation Student

  • (void)study {
    NSLog(@”%@ (ID: %@) is studying.”, self.name, self.studentID);
    }

// 重写父类的方法,并添加自己的逻辑
– (void)sayMyName:(NSString )personName andAge:(NSInteger)personAge andStudentID:(NSString )sID {
// 调用父类的同名方法
[super sayMyName:personName andAge:personAge];
self.studentID = sID;
NSLog(@”And my student ID is %@.”, self.studentID);
}

@end
“`

main.m 中使用 Student

“`objective-c
// main.m
// …

import “Student.h”

int main(int argc, const char * argv[]) {
@autoreleasepool {
// … Person 对象的代码

    Student *alice = [[Student alloc] init];
    [alice sayMyName:@"Alice Smith" andAge:20 andStudentID:@"S12345"]; // 调用子类重写的方法
    [alice study]; // 调用子类特有的方法

    // 访问从Person继承的属性
    NSLog(@"Student's name: %@, age: %ld, ID: %@", alice.name, (long)alice.age, alice.studentID);
}
return 0;

}
“`

协议 (Protocols)

协议定义了一组方法,任何类都可以声明遵守该协议,并实现协议中定义的方法。这类似于Java或C#中的接口。

示例:定义一个 Logger 协议

Logger.h:

“`objective-c
// Logger.h

import

// 声明一个协议
@protocol Logger // 协议也可以继承其他协议,通常继承NSObject协议

@required // 必需实现的方法
– (void)logMessage:(NSString *)message;

@optional // 可选实现的方法
– (void)logError:(NSError *)error;

@end
“`

Person 类遵守 Logger 协议:

Person.h (修改):

objective-c
// Person.h
// ...
@interface Person : NSObject <Logger> // 声明遵守Logger协议
// ...
@end

Person.m (修改,实现协议方法):

“`objective-c
// Person.m
// …
@implementation Person

// 实现协议中的必需方法
– (void)logMessage:(NSString *)message {
NSLog(@”Person Log: %@”, message);
}

// 也可以选择实现可选方法
– (void)logError:(NSError *)error {
NSLog(@”Person Error Log: %@”, [error localizedDescription]);
}

// … 其他方法
@end
“`

main.m 中使用:

objective-c
// main.m
// ...
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *bob = [[Person alloc] init];
bob.name = @"Bob";
[bob logMessage:@"This is a test log from Bob."];
}
return 0;
}

类别 (Categories)

类别允许你向现有类添加方法,而无需创建子类或修改原始类的实现。这对于扩展Apple框架中的类非常有用。

示例:为 NSString 添加一个 reverseString 方法

NSString+Reverse.h:

“`objective-c
// NSString+Reverse.h

import

@interface NSString (Reverse) // 在括号内指定类别名称

  • (NSString *)reverseString;

@end
“`

NSString+Reverse.m:

“`objective-c
// NSString+Reverse.m

import “NSString+Reverse.h”

@implementation NSString (Reverse)

  • (NSString )reverseString {
    NSMutableString
    reversedString = [NSMutableString string];
    NSInteger charIndex = [self length];
    while (charIndex > 0) {
    charIndex–;
    NSRange range = NSMakeRange(charIndex, 1);
    [reversedString appendString:[self substringWithRange:range]];
    }
    return reversedString;
    }

@end
“`

main.m 中使用:

“`objective-c
// main.m
// …

import “NSString+Reverse.h” // 导入类别头文件

int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString original = @”Hello World”;
NSString
reversed = [original reverseString];
NSLog(@”Original: %@, Reversed: %@”, original, reversed);
}
return 0;
}
“`

内存管理:ARC (Automatic Reference Counting)

在现代Objective-C开发中,Apple引入了ARC来简化内存管理。你不再需要手动调用retainreleaseautorelease。编译器会自动插入这些调用。

理解核心概念:
* 强引用 (strong): 默认行为。只要有一个强引用指向一个对象,该对象就会保留在内存中。当所有强引用都消失时,对象就会被释放。
* 弱引用 (weak): 不会增加对象的引用计数。当对象被释放时,弱引用会自动设置为nil,避免野指针(dangling pointer)问题。常用于避免循环引用,例如代理(delegate)模式。
* 无主引用 (unsafe_unretained): 类似于弱引用,但当对象被释放时,无主引用不会自动设置为nil。如果访问已释放的对象,会导致崩溃。应尽量避免使用,除非有明确的原因。
* 赋值 (assign): 用于非对象类型(如基本数据类型、结构体)。直接进行值拷贝,不涉及引用计数。

@property声明中,我们会使用这些修饰符:
@property (nonatomic, strong) NSString *name;
@property (nonatomic, weak) id <SomeDelegate> delegate;

Foundation 框架基础类

Foundation框架提供了许多核心的非UI类,是Objective-C开发的基础。

  • NSString / NSMutableString 字符串处理。
    • NSString *str = @"Hello"; // 字符串字面量
    • NSString *greeting = [NSString stringWithFormat:@"Hello, %@!", @"World"];
    • NSMutableString *mutableStr = [NSMutableString string];
    • [mutableStr appendString:@"Hi"];
  • NSArray / NSMutableArray 有序的不可变/可变数组。
    • NSArray *names = @[@"Alice", @"Bob", @"Charlie"]; // 数组字面量
    • NSString *firstName = names[0];
    • NSMutableArray *mutableNames = [NSMutableArray array];
    • [mutableNames addObject:@"David"];
  • NSDictionary / NSMutableDictionary 不可变/可变的键值对集合(哈希表)。
    • NSDictionary *personInfo = @{@"name": @"John", @"age": @30}; // 字典字面量
    • NSString *name = personInfo[@"name"];
    • NSMutableDictionary *mutableInfo = [NSMutableDictionary dictionary];
    • mutableInfo[@"city"] = @"New York";
  • NSNumber 用于将基本数据类型(如int, float, BOOL)封装成对象。
    • NSNumber *num = @123; // 数字字面量
    • int myInt = [num intValue];

总结与下一步

通过本教程,你已经掌握了Objective-C的以下基础:
* 语言的背景和特点。
* Xcode开发环境的搭建。
* 基本语法、数据类型和NSLog
* 类的定义 (@interface, @implementation)、属性 (@property)、实例方法和类方法。
* 对象的创建和消息发送。
* 继承的概念和super关键字。
* 协议 (@protocol) 的定义和使用。
* 类别 (Category) 扩展现有类。
* ARC内存管理的基础概念 (strong, weak, assign)。
* Foundation框架中常用的基本集合类。

下一步学习建议:
1. 实践: 动手编写更多代码,创建自己的类,尝试不同的场景。
2. Cocoa/Cocoa Touch框架: Objective-C的强大之处在于其与Apple的框架紧密结合。学习如何使用UIKit (iOS) 或 AppKit (macOS) 来构建用户界面。
3. 委托模式 (Delegate Pattern): 这是一个在Objective-C和Swift中非常常见的通信模式,与协议紧密相关。
4. Block: 类似于C语言中的函数指针或Lambda表达式,是Objective-C中处理回调和并发的重要工具。
5. Swift: 随着对Objective-C的理解加深,你将更容易过渡到现代的Swift语言,并理解它们之间的互操作性。

祝你在Objective-C的学习旅程中一切顺利!
“`

滚动至顶部