ios学习路线 -- objective-c 基础

1. OC文件扩展名

.h 头文件,其中包含类,类型,函数和常数的说明

.m 源代码文件, 这是典型的源代码文件扩展名,可以包含 Objective-C 和 C 代码。

.mm 源代码文件,除了可以包含Objective-C和C代码以外还可以包含C++代码。仅在你的Objective-C代码中确实需要使用C++类或者特性的时候才用这种扩展名。

note:#import 选项和 #include 选项完全相同,只是它可以确保相同的文件只会被包含一次。在编写OC项目的时候我们总会使用#import

2. OC的语法

在除了面向对象的语法外,所有其他非面向对象的语法,包括变量类型,预处理器(preprocessing),流程控制,函数声明与调用皆与C语言完全一致。

3. OC中消息的传递

在OC中,调用方法视为给对象发消息,所有方法都视为对消息的响应,所有消息处理都是等到运行时才做动态处理的,并且交给类自己决定要如何去处理这条消息,一个类别不保证一定会回应收到的消息,如果类别收到了一个无法处理的消息,程序只会抛出异常,不会出错或崩溃。

复制代码
[obj method: argument];

4. OC中的字符串

在OC中,通常不使用c语言风格的字符串,而是将字符串传递给NSString这个对象

Objective-C提供了一个助记符可以方便地从常量值创建NSString对象

5. OC中的类

类是用来封装数据的

5.1 类的声明与实现

Objective-C 的类规格说明包含了两个部分:定义(interface)与实现(implementation)。定义(interface)部分包含了类声明和实例变量的定义,以及类相关的方法。实现(implementation)部分包含了类方法的实际代码。

类声明总是由 @interface 编译选项开始,由 @end 编译选项结束。类名之后的(用冒号分隔的)是父类的名字。

其中前缀为减号的为实例方法,加号的为类方法

OC中的方法定义,名称内的冒号(:)代表参数传递,

复制代码
- (void) setColorToRed: (float)red Green: (float)green Blue:(float)blue; /* 宣告方法*/

实现区块则包含了公开方法的实现,以及定义私有(private)变量及方法。 以关键字@implementation作为区块起头,@end结尾。

Objective-C创建对象需通过alloc以及init两个消息。alloc的作用是分配内存,init则是初始化对象。

复制代码
MyObject * my = [[MyObject alloc] init];

如果子类定义了跟父类的具有相同标识符的方法,那么子类首先收到消息,然后可以有选择的把消息转发(也可以不转发)给他的父类。

Objective-C允许你使用嵌套消息。每个嵌套消息的返回值可以作为其他消息的参数或者目标,可以避免过多的本地局部变量

5.2 属性

属性是用来代替声明存取方法的便捷方式

基本的定义使用@property编译选项,紧跟着类型信息和属性的名字

关键字 作用 使用场景
strong 强引用:拥有对象所有权,引用计数 +1,对象不会被提前释放 绝大多数对象类型的默认选择(ARC 环境下),如控制器、模型、数组等
weak 弱引用:不拥有对象所有权,引用计数不变,对象销毁后自动置为 nil 避免循环引用(如 delegate、block 中引用 self、子控件引用父控件)
copy 拷贝:赋值时复制一份新对象,原对象修改不影响当前对象 不可变对象(如 NSString)、不可变集合(NSArray)、block 等
assign 简单赋值:仅赋值内存地址 / 数值,不管理引用计数 基本数据类型(NSIntegerCGFloatBOOL)、C 语言类型(intfloat)、id 以外的指针(如 CGPoint *
unsafe_unretained 不安全的弱引用:不拥有所有权,对象销毁后不会自动置 nil,可能野指针 兼容老旧系统(iOS 4 以下),替代 weak,但存在野指针风险,极少使用
关键字 作用 注意事项
atomic 原子性:存取方法加锁,保证同一时间只有一个线程访问(默认值) 仅保证存取方法的原子性,不保证线程安全(如多线程读写仍可能出问题),性能低
nonatomic 非原子性:存取方法不加锁,性能更高 开发中绝大多数场景的选择(iOS 开发几乎必用),牺牲少量安全性换性能
关键字 作用 补充说明
readwrite 可读可写:自动生成 getter 和 setter 方法(默认值) 类的 .m 文件中可重写 getter/setter 自定义逻辑
readonly 只读:仅自动生成 getter 方法,不生成 setter 方法 如需在类内部修改,可在 .m 文件中通过 class_extension 重新声明为 readwrite
关键字 作用 示例
getter=<方法名> 自定义 getter 方法的名称 @property (nonatomic, assign, getter=isSelected) BOOL selected;(布尔属性常用,生成 -isSelected 方法)
setter=<方法名>: 自定义 setter 方法的名称(注意末尾必须加 : @property (nonatomic, copy, setter=setUserName:) NSString *name;(生成 -setUserName: 方法)
5.3 协议

一系列方法和属性的声明列表,任何类都可以声明自身实现了某个协议

协议中可以使用@optional来表示一个方法可以选择性实现

5.4 转发

由于OC的运行时机制,我们在给一个对象发送消息的时候,不管其是否可以响应这个消息

当一个对象收到消息的时候,除了可以处理和丢弃外,还可以进行转发

复制代码
// 转发方法
- (retval_t) forward:(SEL) sel :(arglist_t) args; // with GCC
- (id) forward:(SEL) sel :(marg_list) args; // with NeXT/Apple systems

// 响应方法
- (retval_t) performv:(SEL) sel :(arglist_t) args;  // with GCC
- (id) performv:(SEL) sel :(marg_list) args; // with NeXT/Apple systems
5.5 分类

一个分类可以将方法的实现分解进一系列分离的文件。程序员可以将一组相关的方法放进一个分类,使程序更具可读性。

分类中的方法是在运行时被加入类中的,这一特性允许程序员向现存的类中增加方法

在运行时,分类中的方法与类原有的方法并无区别,其代码可以访问包括私有类成员变量在内的所有成员变量。

若分类声明了与类中原有方法同名的函数,则分类中的方法会被调用,如果两个分类声明了同名方法,调用取决于编译顺序

6. 自动释放池

自动释放池的核心作用:延迟释放对象 ------ 把对象标记为 "待释放",等到自动释放池销毁时,再统一给这些对象发送 release 消息,避免手动管理内存的繁琐,同时防止对象提前释放或内存泄漏。

复制代码
@autoreleasepool {
    // 块内的自动释放对象,会被加入当前池
    NSString *str = [NSString stringWithFormat:@"test"]; // 该方法内部已调用 autorelease
} // 大括号结束,释放池销毁,自动给池内对象发 release

OC 的自动释放池底层不是单一的 "池",而是由 AutoreleasePoolPage 这个 C++ 类实现的双向链表

每个池对应一个 "标记位"(POOL_BOUNDARY,空对象),加入链表时会先插入这个标记;

池销毁时,从链表尾部往回遍历,直到遇到自己的 POOL_BOUNDARY,给中间所有对象发 release,并重置栈顶指针。

iOS 主线程会自动创建隐式的自动释放池 :RunLoop 每一次循环(kCFRunLoopBeforeWaiting 阶段),都会创建一个新的自动释放池,循环结束时销毁池,释放所有自动释放对象。这也是为什么主线程中创建的自动释放对象,不会立即泄漏的原因。

note: 自动释放池只会是释放autorelease的对象

相关推荐
胡萝卜术1 天前
力扣5. 最长回文子串
前端·javascript·面试
触底反弹1 天前
🔥 从零搭建 RAG 知识库:爬虫→分词→向量化→检索,一步都不能错
javascript·人工智能·面试
ychqsq1 天前
88.归途
经验分享·职场和发展
CoderYanger2 天前
A.每日一题:3020. 子集中元素的最大数量
java·程序人生·算法·leetcode·面试·职场和发展·学习方法
lvchaoq2 天前
this指向面试代码输出题目合集
javascript·面试·职场和发展
wuqingshun3141592 天前
MySQL 如何解决深度分页问题?
java·mysql·面试
weixin_727535622 天前
JVM 常见八股面试问答:深入底层原理
jvm·面试·职场和发展
想吃火锅10052 天前
【leetcode】5.最长回文子串js
算法·leetcode·职场和发展
CoderYanger2 天前
A.每日一题:1967题+1331题
java·程序人生·算法·leetcode·面试·职场和发展·学习方法