Object-C基础学习文档

Objective-C 基础语法详细解析

Objective-C(简称 OC)是苹果生态(iOS、macOS、watchOS、tvOS)的核心开发语言,基于 C 语言扩展而来,既保留了 C 语言的底层能力,又引入了面向对象编程(OOP)特性,同时兼容 C 语言语法。以下从文件结构、数据类型、核心语法、面向对象特性到特有机制,全面梳理 OC 基础语法体系。

一、OC 工程核心:文件结构与编译逻辑

OC 代码通过 头文件(.h)实现文件(.m) 配合实现功能,二者分工明确,是 OC 项目的基础组成单元。

文件类型 后缀 核心作用 包含内容 引用方式
头文件 .h 对外暴露接口("说明书") 类声明、方法声明、属性声明、宏定义、枚举、协议定义 #import "文件名.h"#import <框架名/文件名.h>
实现文件 .m 实现内部逻辑("具体功能") 类的方法实现、私有变量定义、私有方法实现 仅需在内部 #import 对应头文件

关键规则:

  1. #import#include 的区别#import 会自动防止头文件重复引入,无需手动加 #ifndef 保护,是 OC 中推荐的引用方式;#include 是 C 语言语法,可能导致重复引入。

  2. 框架头文件引用 :系统框架(如 Foundation、UIKit)的头文件用尖括号 <>,自定义头文件用双引号 "",例如:

    objc 复制代码
    #import <Foundation/Foundation.h> // 系统框架头文件
    #import "Person.h" // 自定义头文件

二、数据类型体系:从基础到对象

OC 的数据类型分为 基本数据类型 (兼容 C 语言)和 对象数据类型(OC 专属),二者在内存存储、访问方式上有本质区别。

1. 基本数据类型(栈内存存储,效率高)

完全兼容 C 语言,同时新增 OC 专属布尔类型,适用于存储简单数值和状态。

类型类别 具体类型 字节数(64位系统) 取值范围/说明 示例代码
整型 int 4字节 -2³¹ ~ 2³¹-1 int score = 95;
long 8字节 -2⁶³ ~ 2⁶³-1 long userId = 1234567890123;
NSInteger 自适应(4/8字节) 兼容 32/64 位系统,OC 推荐使用 NSInteger age = 25;
浮点型 float 4字节 单精度,精度约 6-7 位小数 float weight = 62.5f;(必须加 f 标识)
double 8字节 双精度,精度约 15-17 位小数 double height = 1.83;
CGFloat 自适应(4/8字节) 图形框架(Core Graphics)专用,OC 绘图推荐 CGFloat radius = 10.5;
字符型 char 1字节 ASCII 字符(0-127) char gender = 'M';
布尔型 BOOL 1字节 OC 专属,本质是 typedef signed char BOOL,取值 YES(1)或 NO(0) BOOL isStudent = YES;

注意:OC 中 不推荐 使用 C 语言的 _Bool 或 C++ 的 bool,统一用 BOOL + YES/NO

2. 对象数据类型(堆内存存储,引用访问)

OC 的核心数据类型,本质是"类的实例",必须通过 指针(* 访问,常用系统对象类型如下:

对象类型 用途 示例代码 关键特性
NSString 字符串处理 NSString *name = @"张三"; 不可变字符串,需用 @ 标识字面量,支持拼接、截取等操作
NSMutableString 可变字符串 NSMutableString *desc = [NSMutableString stringWithString:@"Hello"]; 可动态添加、修改字符串内容
NSArray 不可变数组 NSArray *hobbies = @[@"篮球", @"编程"]; 存储对象集合,不可修改长度,元素需为 OC 对象
NSMutableArray 可变数组 NSMutableArray *list = [NSMutableArray array]; [list addObject:@"苹果"]; 可动态添加、删除元素
NSDictionary 不可变字典 NSDictionary *user = @{@"name": @"李四", @"age": @22}; 键值对集合,键必须是不可变对象(如 NSString
NSNumber 基本类型包装 NSNumber *count = @10; NSNumber *price = @39.9; 将基本类型(int、float 等)包装为对象,用于集合存储

关键规则:

  • 指针必须加 * :对象变量本质是指向堆内存的指针,声明时必须加 *,例如 NSString *str 而非 NSString str
  • 字面量加 @ :OC 对象的字面量(字符串、数组、字典)需用 @ 与 C 语言区分,例如 @"字符串"(OC) vs "字符串"(C);
  • 空指针 nil :对象未初始化时,需赋值为 nil(OC 专属空指针),避免野指针,例如 NSString *emptyStr = nil;

三、面向对象核心:类与对象

OC 是纯面向对象语言,一切功能围绕"类"(模板)和"对象"(实例)展开,通过 @interface(声明)和 @implementation(实现)完成类的定义。

1. 类的声明(.h 文件)

@interface 关键字定义类的"对外接口",包括类名、父类、公共属性、公共方法,是其他类调用该类的"入口"。

示例:Person.h(声明 Person 类)
objc 复制代码
#import <Foundation/Foundation.h> // 引入基础框架,NSObject 所在头文件

// 声明 Person 类,继承自 NSObject(OC 所有类的根类)
@interface Person : NSObject

#pragma mark - 公共属性(用 @property 声明,编译器自动生成 getter/setter)
// 属性格式:@property (修饰符) 类型 *属性名;(基本类型无需 *)
@property (nonatomic, copy) NSString *name;       // 姓名:copy 修饰不可变字符串,防止外部修改
@property (nonatomic, assign) NSInteger age;      // 年龄:assign 修饰基本类型
@property (nonatomic, assign, getter=isStudent) BOOL student; // 是否学生:重命名 getter 为 isStudent

#pragma mark - 公共方法声明
// 实例方法:- 开头,需通过对象调用,格式:- (返回值类型) 方法名:参数1 参数名2:参数2...;
- (void)sayHello; // 无参数,无返回值
- (void)eat:(NSString *)food; // 1个参数(food:食物名称)
- (NSString *)introduceWithHobby:(NSString *)hobby; // 带返回值(自我介绍字符串)

// 类方法:+ 开头,直接通过类调用,常用于工厂方法(创建对象)
+ (Person *)personWithName:(NSString *)name age:(NSInteger)age;

@end
核心细节:@property 修饰符

修饰符控制属性的内存管理、线程安全、读写权限,是 OC 属性的核心配置,常用组合如下:

修饰符类别 可选值 作用 适用场景
内存管理 strong 强引用:对象引用计数 +1,只要有强引用,对象不释放 大多数对象属性(如 NSString *name
weak 弱引用:不增加引用计数,对象释放后自动置为 nil 避免循环引用(如代理属性 @property (nonatomic, weak) id<Delegate> delegate
copy 拷贝:赋值时拷贝一份新对象,原对象修改不影响当前属性 不可变对象(NSStringNSArrayNSDictionary
assign 赋值:直接赋值,不管理内存 基本类型(NSIntegerBOOLCGFloat
线程安全 nonatomic 非线程安全:不保证多线程下读写安全,效率高 移动端开发(绝大多数场景,UI 线程单线程访问)
atomic 线程安全:保证多线程下读写安全,效率低 多线程频繁读写的属性(极少用)
读写权限 readwrite 可读写:自动生成 getter + setter(默认) 需外部修改的属性(如 nameage
readonly 只读:仅生成 getter,无 setter 不允许外部修改的属性(如 userId

2. 类的实现(.m 文件)

@implementation 关键字实现类的"内部逻辑",包括方法的具体代码、私有变量、私有方法,仅在当前 .m 文件可见。

示例:Person.m(实现 Person 类)
objc 复制代码
#import "Person.h" // 引入当前类的头文件

// 实现 Person 类
@implementation Person

#pragma mark - 私有变量(仅 .m 内部可见,外部无法访问)
NSString *_privateID; // 私有 ID,存储内部标识

#pragma mark - 公共方法实现
- (void)sayHello {
    // self.属性名:调用属性的 getter 方法,获取属性值
    NSLog(@"大家好!我是%@", self.name);
}

- (void)eat:(NSString *)food {
    NSLog(@"%@正在吃%@", self.name, food);
}

- (NSString *)introduceWithHobby:(NSString *)hobby {
    // 字符串拼接:用 [NSString stringWithFormat:],占位符 %@ 对应对象
    return [NSString stringWithFormat:@"我叫%@,今年%ld岁,喜欢%@", 
            self.name, (long)self.age, hobby]; // NSInteger 转 long 避免警告
}

// 类方法实现:工厂方法,简化对象创建
+ (Person *)personWithName:(NSString *)name age:(NSInteger)age {
    // 1. alloc:为对象分配堆内存(引用计数 = 1)
    // 2. init:初始化对象属性和状态
    Person *person = [[Person alloc] init];
    // 调用 setter 方法赋值
    person.name = name;
    person.age = age;
    return person;
}

#pragma mark - 私有方法(仅 .m 内部可见,外部无法调用)
- (void)privateMethod {
    NSLog(@"这是 Person 类的私有方法,外部无法访问");
}

@end
核心细节:
  • 对象创建流程 :OC 创建对象必须经过 alloc(分配内存)和 init(初始化)两步,缺一不可,简写为 [[类名 alloc] init]
  • self 关键字 :实例方法中 self 代表"当前对象",类方法中 self 代表"当前类",用于访问当前对象的属性/方法,例如 [self sayHello](调用当前对象的 sayHello 方法);
  • NSLog 打印 :OC 标准打印函数,格式为 NSLog(@"格式化字符串", 参数1, 参数2...),常用占位符:
    • %@:打印 OC 对象(调用对象的 description 方法);
    • %ld:打印 NSIntegerlong 类型;
    • %f:打印 floatdouble 类型;
    • %d:打印 int 类型。

3. 对象的使用(消息传递机制)

OC 调用方法的本质是"向对象发送消息",而非传统的"函数调用",语法格式为 [接收者 消息](接收者可以是对象或类,消息即方法名+参数)。

示例:main.m(程序入口,使用 Person 对象)
objc 复制代码
#import <Foundation/Foundation.h>
#import "Person.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool { // 自动释放池:管理 OC 对象内存,避免泄漏
        // 方式1:通过 alloc + init 创建对象
        Person *person1 = [[Person alloc] init];
        // 调用 setter 方法赋值(两种等价写法)
        person1.name = @"李四"; // 简化写法(推荐)
        [person1 setAge:22];    // 原始消息写法
        person1.student = YES;
        
        // 调用实例方法
        [person1 sayHello]; // 输出:大家好!我是李四
        [person1 eat:@"苹果"]; // 输出:李四正在吃苹果
        NSString *intro1 = [person1 introduceWithHobby:@"游泳"];
        NSLog(@"%@", intro1); // 输出:我叫李四,今年22岁,喜欢游泳
        
        // 方式2:通过类方法(工厂方法)创建对象(简化流程)
        Person *person2 = [Person personWithName:@"王五" age:25];
        [person2 sayHello]; // 输出:大家好!我是王五
        
        // 调用 getter 方法获取属性值(两种等价写法)
        NSString *name1 = person1.name; // 简化写法(推荐)
        NSString *name2 = [person2 name]; // 原始消息写法
        NSLog(@"person1 姓名:%@,person2 姓名:%@", name1, name2);
    }
    return 0;
}
关键特性:
  • 自动释放池(@autoreleasepool :OC 内存管理的核心机制之一,池中标记为"自动释放"的对象,会在池结束时自动释放(调用 release),避免内存泄漏;移动端开发中,UIKit 会自动创建释放池,仅需在 main 函数或异步线程中手动添加;
  • 空指针安全 :若接收者是 nil(空指针),发送消息不会崩溃,返回值为 nil(对象类型)或 0(基本类型),例如 Person *nilPerson = nil; [nilPerson sayHello];(无崩溃,无输出)。

四、OC 特有语法:协议、分类、Block

除基础面向对象特性外,OC 提供协议、分类、Block 三种特有机制,用于解耦、代码复用和异步回调。

1. 协议(Protocol):类似"接口"

定义一套"必须/可选实现的方法",类通过 <协议名> 遵守协议,实现协议中的方法,常用于代理模式(解耦)。

示例 1:定义协议(MyProtocol.h)
objc 复制代码
#import <Foundation/Foundation.h>

// 声明协议,继承自 NSObject 协议(OC 所有协议的根协议)
@protocol MyProtocol <NSObject>

// 必须实现的方法(@required,默认,不写也为必须)
- (void)mustDoTask;

// 可选实现的方法(@optional,可实现也可不实现)
@optional
- (void)optionalTask;

@end
示例 2:类遵守协议(Person.h 中声明)
objc 复制代码
// Person 类遵守 MyProtocol 协议
@interface Person : NSObject <MyProtocol>
// ... 原有属性和方法
@end
示例 3:实现协议方法(Person.m 中)
objc 复制代码
@implementation Person
// ... 原有方法实现

// 必须实现协议的 mustDoTask 方法(不实现会报警告)
- (void)mustDoTask {
    NSLog(@"%@ 完成了必须执行的任务", self.name);
}

// 可选实现 optionalTask 方法(可省略)
- (void)optionalTask {
    NSLog(@"%@ 完成了可选任务", self.name);
}

@end
应用场景:代理模式

例如 iOS 中 UITableViewUITableViewDelegate 协议,控制器通过实现协议方法控制表格的点击、高度等,本质是"协议定义规则,类实现规则",实现代码解耦。

2. 分类(Category):扩展类功能(续)

在不修改原类代码的前提下,为类 新增方法 (不能直接新增属性,需通过关联对象间接实现),常用于拆分庞大类的代码、扩展系统类功能(如为 NSString 新增字符串处理方法)。

示例 1:为系统类 NSString 扩展分类(新增字符串处理方法)

首先创建分类文件(NSString+Extension.hNSString+Extension.m):

头文件(NSString+Extension.h)

声明分类的公共方法,格式为 @interface 原类名 (分类名)

objc 复制代码
#import <Foundation/Foundation.h>

// 为 NSString 类添加名为 Extension 的分类
@interface NSString (Extension)

// 新增方法:判断字符串是否为纯数字
- (BOOL)isPureNumber;

// 新增方法:截取字符串前 N 个字符
- (NSString *)substringWithLength:(NSInteger)length;

@end

实现文件(NSString+Extension.m)

实现分类的方法,格式为 @implementation 原类名 (分类名)

objc 复制代码
#import "NSString+Extension.h"

@implementation NSString (Extension)

// 实现"判断纯数字"方法
- (BOOL)isPureNumber {
    // 正则表达式匹配纯数字
    NSString *regex = @"^[0-9]*$";
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    return [predicate evaluateWithObject:self];
}

// 实现"截取前 N 个字符"方法(处理越界情况)
- (NSString *)substringWithLength:(NSInteger)length {
    // 若长度超过字符串本身,直接返回原字符串
    if (length >= self.length) {
        return self;
    }
    // 调用系统方法截取,避免越界
    return [self substringToIndex:length];
}

@end
示例 2:使用分类方法

引入分类头文件后,所有 NSString 对象均可直接调用分类新增的方法:

objc 复制代码
#import <Foundation/Foundation.h>
#import "NSString+Extension.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSString *str1 = @"123456";
        NSString *str2 = @"abc123";
        
        // 调用分类方法判断纯数字
        NSLog(@"str1 是否纯数字:%@", [str1 isPureNumber] ? @"YES" : @"NO"); // 输出 YES
        NSLog(@"str2 是否纯数字:%@", [str2 isPureNumber] ? @"YES" : @"NO"); // 输出 NO
        
        // 调用分类方法截取前 3 个字符
        NSString *subStr1 = [str1 substringWithLength:3];
        NSLog(@"str1 前3个字符:%@", subStr1); // 输出 123
    }
    return 0;
}
分类的关键规则:
  1. 不能直接新增属性 :分类的 @interface 中声明的属性,编译器不会自动生成 getter/setter 和成员变量,需通过 objc_setAssociatedObjectobjc_getAssociatedObject 关联对象实现(见下文补充);
  2. 方法优先级:若分类方法与原类方法同名,分类方法会覆盖原类方法(编译警告,不推荐);若多个分类方法同名,最后编译的分类方法生效;
  3. 系统类扩展 :可直接为 NSStringNSArray 等系统类添加分类,无需修改系统源码,是 OC 灵活扩展的核心特性。
补充:分类中"间接新增属性"(关联对象)

通过 Runtime 库的关联对象机制,可在分类中为类添加"伪属性",示例如下(为 Person 类分类新增 address 属性):

Person+Address.h

objc 复制代码
#import "Person.h"

@interface Person (Address)

// 声明关联属性
@property (nonatomic, copy) NSString *address;

@end

Person+Address.m

objc 复制代码
#import "Person+Address.h"
#import <objc/runtime.h> // 引入 Runtime 库

// 定义关联对象的 key(唯一标识)
static const void *PersonAddressKey = &PersonAddressKey;

@implementation Person (Address)

// 实现 address 的 getter 方法
- (NSString *)address {
    // 通过 key 获取关联对象
    return objc_getAssociatedObject(self, PersonAddressKey);
}

// 实现 address 的 setter 方法
- (void)setAddress:(NSString *)address {
    // 设置关联对象:参数依次为"宿主对象""key""关联值""内存管理策略"
    objc_setAssociatedObject(self, PersonAddressKey, address, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

@end

使用时与普通属性一致:

objc 复制代码
Person *person = [[Person alloc] init];
person.address = @"北京市朝阳区"; // 调用分类的 setter
NSLog(@"地址:%@", person.address); // 调用分类的 getter,输出 北京市朝阳区

3. Block:匿名函数/闭包

Block 是 OC 中的"匿名函数",可捕获外部变量,常用于 异步回调 (如网络请求回调、动画完成回调)、简化代码逻辑(如集合遍历、排序),语法类似 Swift 的闭包或 JavaScript 的箭头函数。

1. Block 的基本语法

Block 的声明格式为:返回值类型 (^Block名称)(参数列表) = ^(参数列表) { 代码块 };

  • 若无返回值,返回值类型为 void
  • 若无参数,参数列表可省略(仅保留 ());
  • 捕获外部变量时,默认是"值捕获"(不可修改),需加 __block 修饰才能修改。
示例 1:无参数、无返回值的 Block
objc 复制代码
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // 声明并定义 Block(无参数、无返回值)
        void (^PrintHelloBlock)(void) = ^(void) {
            NSLog(@"Hello, Block!");
        };
        
        // 调用 Block(类似函数调用)
        PrintHelloBlock(); // 输出 Hello, Block!
    }
    return 0;
}
示例 2:带参数、带返回值的 Block(计算两数之和)
objc 复制代码
// 声明并定义 Block(参数:两个 int,返回值:int)
int (^AddBlock)(int, int) = ^(int a, int b) {
    return a + b;
};

// 调用 Block 并接收返回值
int result = AddBlock(3, 5);
NSLog(@"3 + 5 = %d", result); // 输出 3 + 5 = 8
示例 3:捕获外部变量(__block 修饰可修改变量)
objc 复制代码
__block int count = 0; // __block 修饰:允许 Block 内部修改外部变量

// Block 内部修改外部变量
void (^IncrementBlock)(void) = ^ {
    count++; // 若不加 __block,编译报错
    NSLog(@"当前 count:%d", count);
};

IncrementBlock(); // 输出 当前 count:1
IncrementBlock(); // 输出 当前 count:2
2. Block 的应用场景:异步回调

最典型的场景是"网络请求回调"------网络请求是异步操作,请求完成后通过 Block 通知调用者结果(类似 Android 的 Callback)。

示例:模拟网络请求工具类(NetworkTool.h/NetworkTool.m

objc 复制代码
// NetworkTool.h
#import <Foundation/Foundation.h>

// 定义回调 Block 类型(简化声明,用 typedef 重命名)
typedef void (^RequestSuccessBlock)(NSString *responseData); // 成功回调:返回响应数据
typedef void (^RequestFailureBlock)(NSError *error);        // 失败回调:返回错误信息

@interface NetworkTool : NSObject

// 声明网络请求方法(参数含成功/失败 Block)
+ (void)sendRequestWithURL:(NSString *)url 
                   success:(RequestSuccessBlock)success 
                   failure:(RequestFailureBlock)failure;

@end
objc 复制代码
// NetworkTool.m
#import "NetworkTool.h"

@implementation NetworkTool

+ (void)sendRequestWithURL:(NSString *)url 
                   success:(RequestSuccessBlock)success 
                   failure:(RequestFailureBlock)failure {
    // 模拟异步网络请求(用 GCD 延迟 2 秒执行)
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_global_queue(0, 0), ^{
        // 模拟请求结果:若 URL 包含"success",则成功;否则失败
        if ([url containsString:@"success"]) {
            // 调用成功 Block,传递响应数据
            if (success) { // 先判断 Block 是否为空,避免崩溃
                success(@"请求成功!响应数据:{\"code\":200,\"data\":\"OK\"}");
            }
        } else {
            // 调用失败 Block,传递错误信息
            if (failure) {
                NSError *error = [NSError errorWithDomain:@"NetworkError" 
                                                     code:404 
                                                 userInfo:@{NSLocalizedDescriptionKey:@"请求失败,URL 错误"}];
                failure(error);
            }
        }
    });
}

@end

使用网络工具类(通过 Block 接收回调):

objc 复制代码
#import <Foundation/Foundation.h>
#import "NetworkTool.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSLog(@"开始发送请求...");
        
        // 调用网络请求方法,传入成功/失败 Block
        [NetworkTool sendRequestWithURL:@"https://example.com/success" 
                               success:^(NSString *responseData) {
                                   // 成功回调:在主线程更新 UI(示例中仅打印)
                                   NSLog(@"请求成功:%@", responseData);
                               } 
                               failure:^(NSError *error) {
                                   // 失败回调:处理错误
                                   NSLog(@"请求失败:%@", error.localizedDescription);
                               }];
        
        // 阻塞主线程,等待异步回调(实际开发中无需此操作,UI 线程会自动循环)
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:3]];
    }
    return 0;
}
Block 的关键注意事项:
  1. 避免循环引用 :若 Block 捕获了"强引用对象"(如 self),且对象又强引用 Block(如 Block 是对象的属性),会导致循环引用(内存泄漏)。解决方案是使用 __weak 弱引用

    objc 复制代码
    // 正确写法:用 __weak 修饰 self,避免循环引用
    __weak typeof(self) weakSelf = self; 
    self.requestBlock = ^{
        // Block 内部使用 weakSelf,避免强引用
        [weakSelf updateUIWithData:@"数据"];
    };
  2. Block 为空判断 :调用 Block 前必须判断是否为空(if (block) { block(); }),否则 Block 为 nil 时调用会崩溃;

  3. 内存管理 :Block 默认存储在"栈"中,若需在超出作用域后使用(如异步回调),会自动拷贝到"堆"中(ARC 下自动管理,MRC 下需手动调用 copy)。

五、内存管理:ARC 与引用计数

OC 的内存管理核心是 引用计数(Reference Counting),即通过计数跟踪对象的引用次数:对象被引用时计数 +1,引用释放时计数 -1,计数为 0 时对象销毁(释放堆内存)。

目前 OC 开发默认使用 ARC(Automatic Reference Counting,自动引用计数) ,编译器自动插入 retain(计数 +1)、release(计数 -1)、autorelease(延迟释放)代码,无需手动管理内存;早期的 MRC(Manual Reference Counting)已极少使用。

1. ARC 下的引用类型

ARC 中通过 strong(强引用)和 weak(弱引用)控制对象生命周期:

  • strong 强引用 :默认引用类型,持有对象,使对象引用计数 +1,只要有强引用存在,对象不会被销毁;

    objc 复制代码
    // strong 引用:person 强引用对象,计数 = 1
    Person *person = [[Person alloc] init]; 
  • weak 弱引用 :不持有对象,不改变引用计数,对象被销毁后,weak 引用会自动置为 nil(避免野指针),常用于避免循环引用(如代理属性、Block 捕获 self):

    objc 复制代码
    // weak 引用:weakPerson 不持有对象,计数仍为 1
    __weak Person *weakPerson = person; 

2. 自动释放池(@autoreleasepool

@autoreleasepool 是 ARC 中管理"延迟释放对象"的机制:

  • 调用 [object autorelease](ARC 下编译器自动调用)的对象,会被加入当前自动释放池;

  • 自动释放池结束时(@autoreleasepool 代码块执行完毕),池中所有对象会被统一调用 release,计数 -1;

  • 移动端开发中,UIKit 会在每一次事件循环(如点击、滑动)中自动创建和销毁自动释放池,无需手动添加;仅在批量创建大量临时对象(如循环创建 1000 个 NSString)时,手动添加释放池可避免内存峰值过高:

    objc 复制代码
    // 批量创建临时对象,手动添加释放池优化内存
    for (int i = 0; i < 1000; i++) {
        @autoreleasepool {
            NSString *tempStr = [NSString stringWithFormat:@"临时字符串_%d", i];
            // 使用 tempStr...(使用完毕后,释放池结束时自动释放)
        }
    }

六、OC 与 Swift 的关系

OC 是苹果早期生态的核心语言,而 Swift 是苹果 2014 年推出的现代语言,二者的关系是 兼容共存

  1. 混编支持 :OC 项目可直接引入 Swift 代码(需创建桥接文件 项目名-Bridging-Header.h),Swift 项目也可通过 @objc 暴露接口给 OC 调用;
  2. 底层共享:OC 和 Swift 均基于苹果的 Runtime 运行时系统,可通过 Runtime 机制互相调用类和方法;
  3. 生态迁移:苹果官方推荐新项目使用 Swift,但 OC 仍被大量老项目(如 iOS 系统框架、第三方库)使用,短期内不会被淘汰。

总结

Objective-C 语法的核心特点是"C 语言基础 + 面向对象扩展 + 特有机制":

  1. 文件结构上通过 .h(声明)和 .m(实现)分离接口与逻辑;
  2. 数据类型分为基础类型(兼容 C)和对象类型(OC 专属,需指针访问);
  3. 面向对象通过类(@interface/@implementation)、属性(@property)、消息传递([接收者 消息])实现;
  4. 特有机制(协议、分类、Block)解决解耦、代码复用、异步回调问题;
  5. 内存管理依赖 ARC 和引用计数,自动释放池辅助优化内存。

OC 是苹果生态开发的基础,理解其语法体系不仅能应对老项目维护,也能更深入理解 Swift 与苹果底层框架的设计逻辑。

相关推荐
忧了个桑14 小时前
从Demo到生产:VIPER架构的生产级模块化方案
ios·架构
如此风景14 小时前
AppDelegate 详解
ios
如此风景18 小时前
Swift基础学习文档
ios
Digitally1 天前
如何将iPhone上的隐藏照片传输到电脑
ios·cocoa·iphone
2501_915918411 天前
uni-app 跨平台项目的 iOS 上架流程:多工具组合的高效协作方案
android·ios·小程序·https·uni-app·iphone·webview
Digitally1 天前
如何将iPhone日历传输到电脑
ios·iphone
叶常落1 天前
LaunchScreen是啥?AppDelegate是啥?SceneDelegate是啥?ContentView又是啥?Main.storyboard是啥?
ios
NRatel2 天前
Unity游戏打包——iOS打包pod的重装和使用
游戏·unity·ios·打包
2501_916013742 天前
iOS 文件管理与 uni-app 性能优化实战 多工具协作的完整指南
android·ios·性能优化·小程序·uni-app·iphone·webview