Objective -C Memory Management  内存管理  第一部分

Memory management is part of a more general problem in programming called resource management.

内存管理是资源管理的一部分。

Every computer system has finite resources for your program to use. These include memory, open files, and network connections. If you use a resource, such as by opening a file, you need to clean up after yourself (in this case, by closing the file).

每个电脑资源有限。包括内存,打开文件数,网络连接。如果你打开了一个文件,就应该清理掉。

Our friends in
the Java and scripting worlds have it easy: memory management happens automatically for them, like having their parents clean up their rooms.

java 和它的脚本世界很容易:内存管理对他们是自动的。就像父亲收拾孩子的房间一样。

If we allocate without freeing, we'll leak memory: our program's memory consumption will grow and grow until we run out of memory, and then, the program will crash.

如果分配了内存,却没有回收,那么可能导致内存泄露:我们的程序占用越来越多的内存,直至用完内存,程序崩溃。

1.1 Object Life Cycle   对象声明周期

Just like the birds and the bees out here in the real world, objects inside a program have a life cycle. They're born (via alloc or new); they live (receive messages and do stuff), make friends (via composition and arguments to methods), and eventually die (get freed) when their lives are over. When that happens, their raw materials (memory) are recycled and used for the next generation.

就像现实世界的鸟和蜜蜂一样,在一个程序内部的对象也有生命周期。他们诞生(通过 alloc 和new) ,他们生活(接受消息和东西),他们交朋友(通过组合和参数方法)并最终死去。这样他们原来的材料(内存)被回收再利用。 说的和人一样啊啊啊。

1.2 Reference Counting 

Cocoa uses a technique known as reference counting, also sometimes called retain counting.

利用引用计数或者保留计数。

Every object has an integer associated with it, known as its reference count or retain count.

每个对象都有自己的引用计数

When some chunk of code is interested in an object, the code increases the object's retain count, saying, "I am interested in this object." When that code is done with the object, it decreases the retain count, indicating that it has lost interest in that object.

有代码对一个对象感兴趣,就增加retain count。如果处理完了,就减少retain count。

When the retain count goes to 0, nobody cares about the object anymore (poor object!), so it is destroyed and its memory is returned to the system for reuse.

当retain count 是0时,就等着被回收或处理吧。

When an object is about to be destroyed because its retain count has reached 0, Objective-C automatically sends the object a dealloc message.

如果一个对象将被销毁因为retain count 到达了0

To find out the current retain count, send the retainCount message. Here are the signatures for retain, release and retainCount:

- (id) retain; 

- (oneway void) release;

- (NSUInteger) retainCount;

A retain call returns an id. This enables you to chain a retain call with other message sends, incrementing the object's retain count and then asking it to do some work. For instance, [[car retain] setTire: tire atIndex: 2]; asks car to bump up its retain count and perform the setTire action.

一个retain 调用能增加retain count,然后要求它做一些工作。

1.3 Object ownership 

When something is said to "own an object," that something is responsible for making sure the object gets cleaned up.

当你说你拥有这个对象的时候,那么你也要为他擦屁股。:-)

1.4 Retaining and releasing in accessor 

 

- (void) setEngine: (Engine *) newEngine

{

 engine = [newEngine retain];

 // BAD CODE: do not steal. See fixed version below.

} // setEngine

Engine *engine1 = [Engine new]; // count: 1

[car setEngine: engine1]; // count: 2

[engine1 release]; // count: 1

Engine *engine2 = [Engine new]; // count: 1

[car setEngine: engine2]; // count: 2

Oops! We have a problem with engine1 now: its retain count is still 1.

engine1 的retain count 仍然是1.main()已经释放了它对engine1的索引,但是Car不会。

 

Here's another attempt at writing setEngine:.

另外一种形式的setEngine方法

- (void) setEngine: (Engine *) newEngine

{

 [engine release];

 engine = [newEngine retain];

// More BAD CODE: do not steal. Fixed version below.

} // setEngine

 

 

Engine *engine = [Engine new]; // count: 1

Car *car1 = [Car new];

Car *car2 = [Car new];

[car1 setEngine: engine]; // count: 2

[engine release]; // count 1

[car2 setEngine: [car1 engine]]; // oops!

[car1 engine] returns a pointer to engine, which has a retain count of 1. The first line of setEngine is [engine release], which makes the retain count 0, and the object gets deallocated.

 

[car1 engine]返回一个指针到engine,它的retain count 是1 。而setEngine 的第一行是release engine 。因此retain count 是0.因此对象被重新分配。

 

Here's a better way to write setEngine:

这个setEngine 比较好:

- (void) setEngine: (Engine *) newEngine

{

 [newEngine retain];

 [engine release];

 engine = newEngine;

} // setEngine

In your accessors, if you retain the new object before you release the old object, you'll be safe.

在存储中,如果你保留新的对象在你释放久的对象之前。那么你就安全了。

 

1.5Autorelease  自动释放

cocoa has the concept of the autorelease pool .

cocoa 有自动释放池的概念。

The name provides a good clue.

It's a pool (collection) of stuff, presumably objects, that automatically gets released.

从名字可以看出它大概是自动释放的东西。

NSObject provides a method called autorelease:

- (id) autorelease;

This method schedules a release message to be sent at some time in the future. The return value is the object that receives the message; retain uses this same technique, which makes chaining together calls easy. When you send autorelease to an object, that object is actually added to
an autorelease pool. When that pool is destroyed, all the objects in the pool are sent a release message.

这个方法计划了一个释放信号被送出。 当你发出autorelease 给一个对象,该对象将加入autorelease pool .当pool 被释放,所有在这个pool中得对象将被发出释放信息。

 

- (NSString *) description

{

 NSString *description;

 description = [[NSString alloc]

  initWithFormat: @"I am %d years old", 4];

 return ([description autorelease]);

} // description

So you can write code like this:

NSLog (@"%@", [someObject description]);

 

1.6 销毁的前夕 The Eve of Our Destruction

When does the autorelease pool get destroyed so that it can send a release message to all the objects it contains? For that matter, when does a pool get created in the first place?

什么时候自动释放池被销毁,什么时候资源池被创建?

 

There are two ways you can create an autorelease pool.

有两种方式创建:

(1)Using the @autoreleasepool language keyword.

(2)Using the NSAutoreleasePool object.

第一种:@ autoreleasepool{} 。大括号里面的将放到新的pool中。

The second, and more explicit, method is to use the NSAutoreleasePool object. When you do this, the code between new and release gets to use the new pool.

第二种,用NSAutoreleasePool 

NSAutoreleasePool *pool;

pool = [NSAutoreleasePool new];

...

[pool release];

 

 

int main (int argc, const char *argv[])

{

 NSAutoreleasePool *pool;

 pool = [[NSAutoreleasePool alloc] init];

 RetainTracker *tracker;

 tracker = [RetainTracker new]; // count: 1

 [tracker retain]; // count: 2

 [tracker autorelease]; // count: still 2

 [tracker release]; // count: 1

 NSLog (@"releasing pool");

 [pool release];

 // gets nuked, sends release to tracker

 @autoreleasepool

  {

    RetainTracker *tracker2;

    tracker2 = [RetainTracker new]; // count: 1

    [tracker2 retain]; // count: 2

    [tracker2 autorelease]; // count: still 2

    [tracker2 release]; // count: 1

    NSLog (@"auto releasing pool");

  }

return (0);

} // main

 

[tracker autorelease]; // count: still 2

Then the object gets autoreleased. Its retain count is unchanged: it's still 2. The important thing to note is that the pool that was created earlier now has a reference to this object.

这个对象获得自动释放了。它的retain count 仍是2。但重要的是pool 有这个对象的一个reference了。 

 

 

 

Objective -C Memory Management 内存管理 第一部分的更多相关文章

  1. Objective-C Memory Management 内存管理 2

    Objective-C Memory Management 内存管理  2  2.1 The Rules of Cocoa Memory Management 内存管理规则 (1)When you c ...

  2. [Android Memory] Android内存管理、监测剖析

    转载自:http://blog.csdn.net/anlegor/article/details/23398785 Android内存管理机制: Android内存管理主要有:LowMemory Ki ...

  3. Objective-C(内存管理)

    引用计数器 每个OC对象都有一个占4个字节存储空间的引用计数器 当使用或创建一个对象时,新对象的引用计数器默认是1 retain:可以使引用计数器+1 release:可以是引用计数器-1 retai ...

  4. IOS学习笔记3—Objective C—简单的内存管理

    今天简述一下简单的内存管理,在IOS5.0以后Apple增加了ARC机制(Automatic Reference Counting),给开发人员带来了不少的方便,但是为了能更好的理解IOS内存管理机制 ...

  5. 【译】x86程序员手册13-第5章 内存管理

    Chapter 5 Memory Management 内存管理 The 80386 transforms logical addresses (i.e., addresses as viewed b ...

  6. innodb源码解析 - mem0_.c - 基本内存管理

    The basic element of the memory management is called a memoryheap. A memory heap is conceptually ast ...

  7. ORACLE 11G内存管理方式

    SGA包含的组件: 组件名 说明 参数 buffer cache 存放从数据文件中读取的数据拷贝,所有用户之间是可以共享的 db_cache_size db_keep_cache_size db_re ...

  8. iOS内存管理部分内容

    Objective-C 高级编程 iOS与OS X多线程和内存管理第一章部分讲述了关于ARC的内容,还讲述了关于修饰符的问题,还讲了好多底层的实现的内容,这些底层实现却往往是在面试的过程中经常被遇到的 ...

  9. Flink内存管理源代码解读之基础数据结构

    概述 在分布式实时计算领域,怎样让框架/引擎足够高效地在内存中存取.处理海量数据是一个非常棘手的问题.在应对这一问题上Flink无疑是做得非常杰出的,Flink的自主内存管理设计或许比它自身的知名度更 ...

随机推荐

  1. C从控制台(stdin)输入带空格的字符串到字符数组中

    用scanf("%s",array); 的话遇到空格就停止接收后面的字符了,那怎么才能接收带空格的字符串呢? 1.用 gets() ,它可以接收带空格的字符串, 直到回车才结束输入 ...

  2. python 线程 进程 标识

    s = '%s%s%s%s%s%s%s%s' % ( time.strftime('%Y%m%d %H:%M:%S', time.localtime(time.time())), ' os.getpp ...

  3. Node.js 101(2): Promise and async

    --原文地址:http://blog.chrisyip.im/nodejs-101-package-promise-and-async 先回想一下 Sagase 的项目结构: lib/ cli.js ...

  4. HttpClient服务端发送http请求

    本来以为对跨域问题的处理已经比较熟练了.可以通过jsonp.document.domain+iframe.window.name.window.postMessage.服务器上设置代理页面来解决.但还 ...

  5. 高清摄像头MIPI CSI2接口浅解【转】

    本文转载自:http://blog.csdn.net/u012075739/article/details/44672435 MIPI摄像头常见于手机.平板中,支持500万像素以上高清分辨率.它的全称 ...

  6. Webdriver中关于driver.navigate().to()和driver.get()使用的区别

    先是有一个父页上button弹开一个子页,总共有4个子页,必须前一个页上的必填信息录完,才能在这个页面触发下一个子页. 用driver.navigate().to(baseUrl2),直接跳转到第2个 ...

  7. [转]RF+Selenium2Library元素定位不到的问题

    原文地址:http://m.blog.csdn.net/m0_37553368/article/details/78016729 在基于RobotFramework框架使用Selenium2Libra ...

  8. 使用AngelaSmith.产生测试数据

    1.安装库程序包.打开NUGET库程序包管理器控制台:输入 Install-Package AngelaSmith -Version 1.0.1                //1.1.1版本可能有 ...

  9. HDU2262;Where is the canteen(高斯消元+期望)

    传送门 题意 给出一张图,LL从一个点等概率走到上下左右位置,询问LL从宿舍走到餐厅的步数期望 分析 该题是一道高斯消元+期望的题目 难点在于构造矩阵,我们发现以下结论 设某点走到餐厅的期望为Ek 1 ...

  10. 【Android跨进程】IPC总结

    前言 IPC是Inter-Process Communication的缩写,含义就是进程间通信或者跨进程通信,是指两个进程之间进行数据交换的过程.两个进程可以是两个独立的app也可以是一个app的两个 ...