Objective -C Memory Management 内存管理 第一部分
Objective -C Memory Management??內(nèi)存管理??第一部分
Memory management is part of a more general problem in programming called resource management.
內(nèi)存管理是資源管理的一部分。
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).
每個(gè)電腦資源有限。包括內(nèi)存,打開文件數(shù),網(wǎng)絡(luò)連接。如果你打開了一個(gè)文件,就應(yīng)該清理掉。
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?和它的腳本世界很容易:內(nèi)存管理對他們是自動(dòng)的。就像父親收拾孩子的房間一樣。
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.
如果分配了內(nèi)存,卻沒有回收,那么可能導(dǎo)致內(nèi)存泄露:我們的程序占用越來越多的內(nèi)存,直至用完內(nèi)存,程序崩潰。
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.
就像現(xiàn)實(shí)世界的鳥和蜜蜂一樣,在一個(gè)程序內(nèi)部的對象也有生命周期。他們誕生(通過?alloc?和new) ,他們生活(接受消息和東西),他們交朋友(通過組合和參數(shù)方法)并最終死去。這樣他們原來的材料(內(nèi)存)被回收再利用。 說的和人一樣啊啊啊。
1.2 Reference Counting?
Cocoa uses a technique known as reference counting, also sometimes called retain counting.
利用引用計(jì)數(shù)或者保留計(jì)數(shù)。
Every object has an integer associated with it, known as its reference count or retain count.
每個(gè)對象都有自己的引用計(jì)數(shù)
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.
有代碼對一個(gè)對象感興趣,就增加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.
當(dāng)retain count?是0時(shí),就等著被回收或處理吧。
When an object is about to be destroyed because its retain count has reached 0, Objective-C automatically sends the object a dealloc message.
如果一個(gè)對象將被銷毀因?yàn)閞etain count?到達(dá)了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.
一個(gè)retain?調(diào)用能增加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.
當(dāng)你說你擁有這個(gè)對象的時(shí)候,那么你也要為他擦屁股。:-)
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()已經(jīng)釋放了它對engine1的索引,但是Car不會(huì)。
?
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]返回一個(gè)指針到engine,它的retain count?是1?。而setEngine?的第一行是release engine?。因此retain count?是0.因此對象被重新分配。
?
Here's a better way to write setEngine:
這個(gè)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.
在存儲(chǔ)中,如果你保留新的對象在你釋放久的對象之前。那么你就安全了。
?
1.5Autorelease??自動(dòng)釋放
cocoa has the concept of the autorelease pool .
cocoa?有自動(dòng)釋放池的概念。
The name provides a good clue.
It's a pool (collection) of stuff, presumably objects, that automatically gets released.
從名字可以看出它大概是自動(dòng)釋放的東西。
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.
這個(gè)方法計(jì)劃了一個(gè)釋放信號(hào)被送出。 當(dāng)你發(fā)出autorelease?給一個(gè)對象,該對象將加入autorelease pool .當(dāng)pool?被釋放,所有在這個(gè)pool中得對象將被發(fā)出釋放信息。
?
- (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?
什么時(shí)候自動(dòng)釋放池被銷毀,什么時(shí)候資源池被創(chuàng)建?
?
There are two ways you can create an autorelease pool.
有兩種方式創(chuàng)建:
(1)Using the @autoreleasepool language keyword.
(2)Using the NSAutoreleasePool object.
第一種:@ autoreleasepool{}?。大括號(hào)里面的將放到新的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.
這個(gè)對象獲得自動(dòng)釋放了。它的retain count?仍是2。但重要的是pool?有這個(gè)對象的一個(gè)reference了。?
?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/ljlkfx/p/4480749.html
總結(jié)
以上是生活随笔為你收集整理的Objective -C Memory Management 内存管理 第一部分的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 手工编程:hello world
- 下一篇: NormalMap 贴图 [转]