Effective Objective-C 2.0 读书笔记——内存管理(上)

Effective Objective-C 2.0 读书笔记 第 1 章 熟悉 Objective-C 第 2 章 对象消息运行时 第 3 章 接口和 API 设计 第 4 章 协议与分类 第 5 章 内存管理 循环引用 普通的两个变量互相引用 Block 循环引用 NSTimer 悬挂指针 持有释放不匹配 performselector CoreFoundation - Foundation try catch 其他 autoreleasepool blo 阅读详情

Effective Objective-C 2.0 读书笔记——内存管理(上)


在Objective-C中,内存管理是程序开发中不可或缺的一部分,而自引用计数( ARC)是一种自动化的内存管理技术。本文是对自动引用计数的简单学习,特此进行记录

引用计数

引用计数是一种技术,用于管理对象的引用计数,即对象被引用的次数。当一个对象的引用计数大于0时,表示该对象被持有,不可被释放;当引用计数为0时,表示对象需要被释放。

自引用计数是一种技术,用于管理对象的引用计数,即对象被引用的次数。当一个对象的引用计数大于0时,表示该对象被持有,不可被释放;当引用计数为0时,表示对象需要被释放。

文章用一个办公室关灯的例子十分贴切:

image-20240917202038743

  1. 第一个人进入办公室,“需要照明的人数” 加1。计数值从0 变成了1,因此要开灯。
  2. 之后每当有人进入办公室,“需要照明的人数” 就加1。如计数值从1变成2。
  3. 每当有人下班离开办公室,“需要照明的人数” 就减1。如计数值从2 变成1。
  4. 最后一个人下班离开办公室时,“需要照明的人数” 减1。计数值从1变成了0,因此要 关灯。

image-20240917202235863

// 生成并持有对象
id obj = [[NSObject alloc] init];

// 持有对象
[obj retain];

// 释放对象
[obj release];

// 废弃对象
[obj dealloc];

属性存取方法中的内存管理

在手动计数,我们要使用以下方法对属性进行手动计数

- (void)setFoo:(id)foo {
    if (_foo != foo) {
        [foo retain];//对传入的新对象 foo 调用 retain,使其引用计数加 1
        [_foo release];//释放当前实例变量 _foo 中原来存储的对象
        _foo = foo;//传入的新对象 foo 赋值给实例变量 _foo
    }
}

当执行完 _foo = foo; 后,_foo 和 foo 都指向同一个对象,因此对 _foo 进行 release 就相当于对该对象(也就是 foo 指向的对象)进行 release。

autorelease

关于这个方法,书中给出了这个例子

- (NSString *)stringValue {
    NSString *str = [[NSString alloc] initWithFormat:@"I am this: %@", self];
    return str;
}

由于我们内存管理的原则——谁创建谁释放,在这个方法之中被创建的对象str必须在stringValue之中得到release,但是很明显如果在return语句执行之前进行release的话,则没有返回值。在return之后写release语句则根本不会执行,那么怎么办呢?我们可以将程序修改成以下形式

- (NSString *)stringValue {
    NSString *str = [[NSString alloc] initWithFormat:@"I am this: %@", self];
    return [str autorelease];  // 放入自动释放池中
}

它会在稍后释放对象,从而给调用者留下了足够长的时间 ,使其可以在需要时先保留返回值。实际上,释放操作会在清空最外层的自动释放池 (参见第 34 条)时 执行,除非你有自己的自动释放池 ,否则这个时机指的就是当前线程的下一次事件循环

保留环

image-20250208182130032

保留环顾名思义——就是呈环状相互引用的多个对象,这将导致内存泄漏,因为循环中的对象其保留计数不会降为0。对于循环中的每个对象来说,至少还有另外 一个对象引用着它 。图里的每个对象都引用了 另外两个对象之中的一个。在这个循环里,所有对象的保留计数都是1。

在垃圾收集环境中,通常将这种情况认定为"孤岛" (island of isolation),通常我们使用弱引用解决这个问题

ARC

由于ARC 会自动执行retain、release、autorelease等操作,所以直接在ARC下调用这些内存管理方法是非法的。具体来说,不能调用下列方法:
• retain
• release
• autorelease
• dealloc
直接调用上述任何方法都会产生编译错误,因为ARC要分析何处应该自动调用内存管理方法,所以如果手工调用的话,就会干扰其工作。

ARC必须遵循的方法命名原则

拥有(retained)返回值
如果方法名以 alloc、new、copy 或 mutableCopy 开头,ARC 默认认为该方法返回的对象是“拥有的”(即调用者获得一个 +1 的所有权),调用者负责在不需要时释放它。

示例:

EOCPerson *person = [[EOCPerson alloc] init];
// person 的 retain count +1,调用者需要 release
[person release];

如果方法名 不以 这些前缀开头(如 somePerson),那么返回的对象会被 autorelease,调用者不需要手动 release,否则可能会导致程序崩溃(过度释放)。


2. 示例代码解析

(1) newPerson 方法

objc


复制编辑
+ (EOCPerson*) newPerson {
    EOCPerson *person = [[EOCPerson alloc] init];
    return person;
}
  • 该方法的名字 以 new 开头,所以它返回的对象是 归调用者所有的。
  • alloc 使 person 的 retain count +1,但调用者仍然负责在适当的时候释放 person。

调用方式:

EOCPerson *personOne = [EOCPerson newPerson];
// 由于 newPerson 返回的是 "owned" 对象,调用者需要释放:
[personOne release];

(2) somePerson 方法

+ (EOCPerson*) somePerson {
    EOCPerson *person = [[EOCPerson alloc] init];
    return person;
}
  • 该方法的名字 没有以 new、alloc、copy 或 mutableCopy 开头,所以它返回的对象 不归调用者所有。
  • ARC 会自动在返回对象上调用 autorelease,确保对象在方法返回后仍然有效,但在适当的时候自动释放。

在 MRC(手动引用计数) 下,它等价于:

return [person autorelease];

调用方式:

EOCPerson *personTwo = [EOCPerson somePerson];
// personTwo 被自动 autorelease,调用者不需要手动 release
  • 如果手动调用 [personTwo release],可能会导致程序崩溃!

但是如果调用此类方法想要获取一个长时间持有的对象的话(例如用这类方法赋值给一个属性),我们还是需要对这个进行retain操作

EOCPerson *tmp = [EOCPerson personWithName: @"Bob Smith"]; 
_myperson = [tmp retain];

3. 调用代码分析

-(void) doSomething {
    EOCPerson *personOne = [EOCPerson newPerson];
    EOCPerson *personTwo = [EOCPerson somePerson];
}

在 doSomething 方法里:

  • personOne 通过 newPerson 方法创建,归调用者所有,所以 doSomething 结束时,ARC 需要释放它(如果是 MRC,调用者需要手动 release)。
  • personTwo 通过 somePerson 方法创建,它是 autorelease 对象,不需要手动释放,ARC 会自动管理它。

在 ARC 下,这段代码执行后:

  1. personOne 在作用域结束后被 ARC 释放。
  2. personTwo 在合适的时间点自动释放。

ARC 的自动优化:消除冗余的 autorelease 与 retain

除了自动调用 retain 与 release 之外,ARC 还能进行一些手工难以实现的优化。书中举了这样一个例子:

假设有一个方法 personWithName:,它内部是这样写的:

+ (EOCPerson*) personWithName:(NSString*) name {
    EOCPerson *person = [[EOCPerson alloc] init];
    person.name = name;
    return objc_autoreleaseReturnValue(person);
}

关于objc_autoreleaseReturnValue(person)这个函数,是一个用于优化的函数,其具体作用如下:

检测调用者是否马上会对返回的对象调用 retain:
在某些情形下(例如调用方在赋值时,因为属性是 strong,所以会自动执行一次 retain 操作),实际上调用者会对返回的对象立即执行 retain。这种情况下,原先的 autorelease 操作就显得“多余”了。

优化过程:
如果检测到调用者马上会执行 retain,那么 objc_autoreleaseReturnValue 会设置一个标志位,并不真正执行 autorelease;这样就避免了不必要的 autorelease 和随后的 retain 操作。

那么对于这个方法的调用者来说,我们在调用者侧的代码如下

EOCPerson *tmp = [EOCPerson personWithName:@"Mat Galloway"];
_myPerson = objc_retainAutoreleasedReturnValue(tmp);

这里 objc_retainAutoreleasedReturnValue 的作用与前面的函数相对应:

  • 检测返回对象上是否设置了标志(表明前面已经发现“将被 retain”的情况),
  • 如果标志已置位,则直接返回对象而不执行额外的 retain 操作;
  • 否则,就调用普通的 retain。

对于这两个特殊的优化方法,书中给出他们的伪代码实现

id objc_autoreleaseReturnValue(id object) {
    if (/* caller will retain object */) {
        set_flag(object);  // 标记此对象,表明将会被 retain
        return object;
    } else {
        return [object autorelease];
    }
}

id objc_retainAutoreleasedReturnValue(id object) {
    if (get_flag(object)) {
        clear_flag(object);
        return object;    // 已经标记,直接返回而不需要额外的 retain
    } else {
        return [object retain];
    }
}

设置与检测一个标志位的操作通常比调用 autorelease 和 retain 更高效。ARC 利用这种技术可以使得内存管理的开销降低,从而提升程序整体性能。

变量的内存管理语义

ARC也会处理局部变量与实例变量的内存管理。默认情况下,每个变量都是指向对象的强引用。一定要理解这个问题,尤其要注意实例变量的语义,因为对于某些代码来说,其语义和手动管理引用计数时不同。例如,有下面这段代码:

@interface EOCClass : NSObject (
id _object;
}
@implementation EOCClass
- (void) setup (
  _object = [EOCotherClass new]; 
 }
@end

在手动管理引用计数时,实例变量_object 并不会自动保留其值,而在ARC环境下则会 这样做。也就是说,若在ARC 下编译setup 方法,则其代码会变为:

-(void) setup {
  id tmp = [EOCOtherClass new];
  _object = [tmp retain];
  [tmp release];
}

如果不用ARC,那么需要像下面这样来写:

-(void) setobject: (id) object {
  [_object release];
  _object = [object retain];
}	

在 ARC 下,Objective‑C 引入了几个修饰符来标识变量对对象的所有权,这些修饰符直接影响编译器如何管理变量所引用对象的内存。常见的修饰符包括:

__strong(默认)
  • 语义:
    对象变量默认是 __strong 的,也就是说,当一个对象被赋值给一个 __strong 变量时,该变量会持有对象,使得对象的引用计数增加。

  • 作用:
    保证只要变量存在,对象不会被销毁。当该变量离开作用域或被赋予新值时,原先引用的对象会自动释放(编译器会自动插入 release 操作)。

  • 示例

    :

    NSObject *obj = [[NSObject alloc] init];  // obj 是 __strong 的,retain count 自动 +1
    // 当 obj 离开作用域后,编译器会自动调用 release
    
__weak
  • 语义:
    声明为 __weak 的变量不会对所引用的对象进行所有权保持,即不会增加对象的引用计数。

  • 作用:
    主要用于打破循环引用(例如在 delegate 或块(block)中),当所引用的对象被释放时,__weak 变量会自动置为 nil,防止野指针问题。

  • 示例:

    NSURL *url = [NSURL URLWithString:@"http://www.example.com/"];
    EOCNetworkFetcher *fetcher = [[EOCNetworkFetcher alloc] initWithURL:url];
    __weak EOCNetworkFetcher *weakFetcher = fetcher;
    [fetcher startWithCompletion:^(BOOL success) {
        NSLog(@"Finished fetching from %@", weakFetcher.url);
    }];
    
__unsafe_unretained
  • 语义:
    与 __weak 类似,也不增加引用计数,但不同的是 __unsafe_unretained 变量不会在所引用对象被销毁时自动置为 nil,因此存在野指针风险。

  • 作用:
    主要用于兼容旧代码或在性能上要求极高且确信生命周期管理正确的场景中。

  • 示例:

    __unsafe_unretained NSObject *unsafeObj = someStrongObj;
    // 如果 someStrongObj 被释放,unsafeObj 不会自动置 nil,继续访问会导致崩溃
    
__autoreleasing
  • 语义:
    这种修饰符通常用于方法参数,表示传入的对象在方法返回时将被放入自动释放池。

  • 作用:
    用于处理输出参数,使得返回给调用者的对象不必立即释放,而是在当前自动释放池清空时被释放。

  • 示例:

    - (BOOL)error:(NSError * __autoreleasing *)error;
    

ARC清理实例变量

在使用MRC时,我们会在- (void)dealloc之中手动释放所有被持有的实例变量

- (void)dealloc {
    [_foo release];
    [_bar release];
    [super dealloc];
}

尽管 ARC 可以自动管理所有 Objective‑C 对象的内存,但对于非 Objective‑C 对象仍需要开发者手动清理。例如:

  • Core Foundation 对象:这些对象不受 ARC 管理,需要在 dealloc 中调用 CFRelease。
  • 由 malloc 分配的内存:这类内存同样需要手动调用 free 来释放。

在 ARC 环境下,如果你需要清理这些资源,你可以自己实现 dealloc 方法,但注意不要调用 [super dealloc],因为 ARC 会自动为你调用超类的 dealloc。示例代码可能如下:

- (void)dealloc {
    CFRelease(_coreFoundationObject);
    free(_heapAllocatedMemoryBlob);
    // 不要调用 [super dealloc],ARC 会自动调用超类的 dealloc
}

覆写内存管理方法

在 MRC 下,有时我们会覆写 release 方法(例如在单例中为了防止对象被释放,将 release 改成空操作),但在 ARC 下我们不被允许重写或者是直接调用内存管理方法,因为我们前面有说到ARC会执行各项的相关优化,重写或者直接调用会产生问题。ARC 通过特殊函数(如 objc_autoreleaseReturnValue 和 objc_retainAutoreleasedReturnValue)来优化那些成对出现的 autorelease 与 retain 操作,以减少不必要的调用和提升性能。

Halcon算子知识:optical_flow_mg 光流(Optical Flow)是一种研究图像对齐的算法,一般包括两大类:稀疏光流和稠密光流。稀疏光流就是研究图像中稀疏点的光流,这些点一般是角点;稠密光流则是研究图像中所有点的偏移量。以下介绍halcon的基本光流算子optical_flow_mg的原理方法。该算子计算两个图片的光流法。 二、算子说明 optical_flow_mg(ImageT1, ImageT2 : VectorField : Algorithm, SmoothingSigma, Integration 阅读详情

相关推荐

告别Windows!Oculus Quest 2在Mac M1上的串流实战(scrcpy+SideQuest避坑指南)

本文为Mac M1用户提供了Oculus Quest 2在macOS上实现高清低延迟串流的实战指南。通过使用开源工具scrcpy和SideQuest,绕开官方限制,详细讲解了从环境准备、无线调试到画质与延迟优化的完整步骤,重点解决了Apple Silicon芯片Mac的连接与性能问题,助你告别Windows依赖。

weixin_29224309的博客 303

Effective Objective-C 2.0 读书笔记——内存管理(下)

对象在经历其生命期后 ,最终会为系统所回收 ,这时就要执行dealloc方法了。在每个对象的生命期内,此方法仅执行一次,也就是当保留计数降为0的时候。在这个方法之中,主要就是释放对象所拥有的引用。比如CoreFoundation 对象就必须手工释放,因为它们是由纯C的API 所生成的。在dealloc方法中,通常还要做一件事,那就是把原来配置过的观测行为都清理掉。之前讲到通知传值就有说到,我们当不需要监听后就需要在dealloc函数当中将注册的通知中心进行销注。

aa2002aa的博客 1412

BALM2深度解析 | 港大MARS实验室如何用点簇革新激光BA?

本文深度解析了港大MARS实验室提出的BALM2方案如何通过点簇技术革新激光BA(Bundle Adjustment)处理。BALM2将点云数据聚合为点簇,显著提升计算效率,实测显示其计算耗时仅为传统方法的1/20。文章详细介绍了点簇的核心原理、二阶优化方法及与传统方法的性能对比,展示了其在激光SLAM领域的突破性应用。

weixin_29212867的博客 152

Effective Objective-C 2.0(52个有效方法) —— 内存管理 读书笔记

29、理解引用计数 Retain 递增保留计数 release 递减保留计数 autorelease 待稍后清理“自动释放池”(autorelease pool)时,再递减保留计数 引用计数机制通过可以递增递减的计数器来管理内存。对象创建好之后,其保留计数至少为1,若保留计数为为正, 则对象继续存活。当保留计数降为0时,对象就被销毁了。 在对象生命期中,其余对象通过引用来保留或释放此...

heqiang2015的博客 374

银河麒麟V10 SP3下NFS客户端挂载失败?5个常见问题排查与修复

本文针对银河麒麟V10 SP3系统中NFS客户端挂载失败的常见问题,提供了5个实战排查方案。从基础服务状态检查到防火墙配置、版本兼容性、/etc/fstab设置及权限映射,详细解析了问题根源与解决方案,帮助用户快速恢复NFS文件共享功能。

weixin_42525005的博客 358

STM32G474+Simulink+HIL硬件在环仿真

硬件:STM32G474RET6(官方的NUCLEO板)软件:STM32Cube_FW_G4 V1.6.1芯片包;KeilMATLAB 2023B(本文已成功)STM32嵌入式支持包。

qq_44701116的博客 1779

【Effective Objective-C 2.0读书笔记】第五章:内存管理

Objective-C语言以引用计数来管理内存,这令许多初学者纠结,要是用过以“垃圾收集器”(garbage collector)来管理内存的语言,那么更会如此。“自动引用计数”机制缓解了此问题,不过使用时有很多重要的注意事项,以确保对象模型正确,不致内存泄漏。本章提醒读者注意内存管理中易犯的错误。

freeWayWalker的专栏 1232

基于cnn version_transformer VIT模型的动物图像分类 完整代码+数据 动物分类教程

基于cnn version_transformer VIT模型的动物图像分类 完整代码+数据 动物分类教程

机器学习深度学习业余选手 1001

Effective Objective-C 2.0 读书笔记——关联对象

暑假的任务是学习Effective Objective-C 2.0书上的相关内容,今天终于开始着手写读书笔记,希望能够在寒假多发两篇吧其实关联对象一定程度上是等同于在子类之中添加属性的,只是相对来说,使用关联对象会比写一个子类并且调用其中的方法更加节约资源一点,本质上其实就给我们提供了一个动态修改的空间,更加的灵活。

aa2002aa的博客 1836

手把手教你学simulink实例--基于Simulink的航空发动机控制系统设计与仿真

航空发动机是飞机的核心动力装置,其性能直接影响飞行器的安全性、经济性和可靠性。现代航空发动机控制系统需要具备高精度、快速响应和强鲁棒性的特点,以适应复杂的飞行环境和任务需求。本项目旨在使用MATLAB/Simulink平台,设计并实现一种适用于涡扇发动机的闭环控制系统,通过调节燃油流量、压气机叶片角度等控制变量,确保发动机在不同工况下稳定运行,并满足推力需求。

MHD0815的博客 275

AMBA-AXI and ACE协议详解(十)

本章介绍了ACE协议中的Barrier事务机制,包括内存屏障和同步屏障两种类型。

Crazzy_M的博客 612

《Effective Objective-C 2.0》读书/实战笔记 二

##《Effective Objective-C 2.0》读书/实战笔记 二 第3章:接口与API设计

weixin_33908217的博客 516

药物对接仿真软件:HADDOCK_(9).结果分析方法

HADDOCK是一种强大的药物对接仿真工具,通过对生成的输出文件进行详细的分析,我们可以验证仿真结果的可靠性,并为进一步优化药物设计提供依据。常见的分析方法包括解读输出文件、使用可视化工具进行结构分析、评估对接模型的稳定性和准确性等。通过这些步骤,我们可以更全面地了解受体和配体的结合模式,从而提高药物设计的成功率。

kkchenjj的博客 1004

Effective Objective-C 2.0(52个有效方法) —— 对象、消息、运行期 读书笔记

用Objective-C等面向对象语言编程时,“对象”就是“基本构造单元”,开发者可以通过对象来存储并传递数据,在对象之间传递数据并执行任务的过程就叫做“消息传递”; 当应用程序运行起来以后,为其提供相关支持的代码叫做“Objective-C运行期环境”,它提供了一些使得对象之间能够传递消息的重要函数,并且包含创建类实例所用的全部逻辑。 6、理解“属性”这一概念 可以用“@propert...

heqiang2015的博客 578

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Effective Objective-C 2.0 读书笔记——大中枢派发

队列特定数据允许你将任意数据(以键值对形式)关联到一个特定的 GCD 队列上。这个数据就像“标签”一样,可以让你在执行任务时知道当前任务属于哪个队列。

aa2002aa的博客 1829

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

《Effective Objective-C 2.0》读书笔记——熟悉Objective-C

Objective-C在C语言基础上添加了面向对象特性,代码十分易读,但仍有许多微妙细节需要注意,而且还有许多容易为人所忽视的特性。 另一方面,有些开发者并未完全理解或是容易滥用某些特性,导致写出来的代码难于维护且不易调试。

XY_Mckevince的博客 2098

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Effective objective-c-- 内存管理

寒假比较忙没能能认真看,就拖到学校了来看了,进度落后很多了,只能尽量赶了;

m0_74217598的博客 4176

Effective Objective-C 2.0 读书笔记——协议和分类

协议定义了一系列方法,遵从此协议的对象应该实现它们,我们可以用协议把自己所写的API 之中的实现细节隐藏起来,将返回的对象设计为遵从此协议的纯i d类型。这样做可行,但不太理想。其实就是不命名的分类,没有名字的分类自然没办法在其他地方被应用,这就引申出我们使用它的场景——我们在编程的过程之中只需要对外公布的那部分内容公开,那么不公开的就会被放在。由于我们在编写功能较多的类时,一般都会给每一个代码开辟一个分类,让他负责一部分的功能,但是我们在编写分类时,尽量不要在分类之中添加对应属性,所有的属性都应该在。

aa2002aa的博客 2334

《Effective Objective-C》阅读笔记(下)

使用无缝桥接技术,可以在Foudation框架中的OC对象与CoreFoudation框架中的C语言数据结构之间来回转换。使用无缝桥接,可以将collection转换为具备特殊内存管理语义的collection。比如字典的键为“拷贝”,而值为“保留”,这时就只能使用无缝桥接来改变语义。

2301_80095702的博客 2622

[iOS]小学生的读书采蜜本里有什么-Effective Objective-C 2.0阅读笔记

[iOS]小学生的读书采蜜本里有什么-Effective Objective-C 2.0阅读笔记

m0_74703932的博客 2559

【Effective Objective-C】—— 内存管理

第29条:理解引用计数 OC使用引用计数来管理内存,也就是说,每个对象都有个可以递增或递减的计数器,如果某个对象引用他时就会给其引用计数加1,用完了之后,就递减其计数,直至为0,销毁这个对象。ARC实际上也是一种引用计数机制。 1.引用计数工作原理: 在引用计数架构下,对象有个计数器,用以表示当前有多少个事物想令此对象继续存活下去。NSObject协议声明了下面三个方法用于操作计数器: Retain 递增保留计数 release 递减保留计数 autorelease 待稍后清理“自动释放池”时,再递减

m0_55124878的博客 2420

【Effective Objective - C 2.0】——读书笔记(一)

最近寒假学习了【Effective Objective - C 2.0】这本书,特此总结提示:这里对文章进行总结:例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

weixin_72437555的博客 1136

【Effective Objective - C 2.0】——读书笔记(五)

要管理其内存,ARC就必须在“回收分配给对象的内存”是生产必要的清理代码。

weixin_72437555的博客 1206

effective—Objective—C 第七章阅读笔记

首先我们得认识一下我们这里处理转化,无缝桥接。__ bridge 的意思是ARC仍然具备OC对象的所有权,而 __bridge retained则与之相反,以为值ARC要交出对象的所有权。那么这段代码后面就要加上 CFRelease.与之类似,反向转化可以通过bridge_transfer来实现。这三种方式都叫做桥式转化。之所以会出现无缝衔接的内容,是因为:可是,你也许会问:以纯 Objective-C来编写应用程序时,为何要用到这种功能呢?

qq_73106050的博客 999

读书笔记:Effective Objective-C

语法 2.在类的头文件中尽量少引入其他头文件 除非却有必要,否则不要引入头文件。一般来说,应在某个类的头文件中使用 @class 来提及别的类,并在实现文件中引入那些类的头文件。这样做可以尽量降低类之间的耦合。 有时无法使用向前声明,比如声明类遵循协议。这种情况可以将协议的声明移至“class-continuation 分类”。 3. 使用字面量语法而不是与之等价的方法 创建字符串、数值、数组、字典。 NSNumber *someNumber = @1; NSArray *animals = @[@

Kingyu Luk's Blog 1670

【Effective Objective - C】—— 内存管理

OC是一门面向对象的语言,而面向对象语言里内存管理是一个重要的概念,想用一门语言写出内存使用效率高的代码就得掌握其中的细节,在OC引入ARC模式之后内存管理的事情几乎都是由编译器来决定的,这使我们学习内存管理变得简单许多。

qq_72437394的博客 1019
上一篇: Effective Objective-C 2.0 读书笔记——协议和分类
下一篇: Effective Objective-C 2.0 读书笔记——大中枢派发
小鹿撞出了脑震荡
博客等级 码龄3年 1107粉丝 97原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值