亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

oc內存管理機制

2019-11-14 18:48:27
字體:
來源:轉載
供稿:網友

一直對oc內存管理機制一知半解,今天特意看了一下官方文檔,聊以記之。

本人比較懶在這里直接貼官方文檔啦

//************************//

Use accessor Methods to Make Memory Management Easier

If your class has a PRoperty that is an object, you must make sure that any object that is set as the value is not deallocated while you’re using it. You must therefore claim ownership of the object when it is set. You must also make sure you then relinquish ownership of any currently-held value.

Sometimes it might seem tedious or pedantic, but if you use accessor methods consistently, the chances of having problems with memory management decrease considerably. If you are using retain and release on instance variables throughout your code, you are almost certainly doing the wrong thing.

Consider a Counter object whose count you want to set.

@interface Counter : NSObject
@property (nonatomic, retain) NSNumber *count;
@end;
The property declares two accessor methods. Typically, you should ask the compiler to synthesize the methods; however, it’s instructive to see how they might be implemented.

In the “get” accessor, you just return the synthesized instance variable, so there is no need for retain or release:

- (NSNumber *)count {
    return _count;
}
In the “set” method, if everyone else is playing by the same rules you have to assume the new count may be disposed of at any time so you have to take ownership of the object—by sending it a retain message—to ensure it won’t be. You must also relinquish ownership of the old count object here by sending it a release message. (Sending a message to nil is allowed in Objective-C, so the implementation will still work if _count hasn’t yet been set.) You must send this after [newCount retain] in case the two are the same object—you don’t want to inadvertently cause it to be deallocated.

- (void)setCount:(NSNumber *)newCount {
    [newCount retain];
    [_count release];
    // Make the new assignment.
    _count = newCount;
}

/************************************************/

簡單說就是@{get,set}方法,get方法就不說了,說說set方法

- (void)setCount:(NSNumber *)newCount {
    [newCount retain];   //newCount 引用計數+1
    [_count release];    //把_count 指針所指向的對象引用計數-1  ,沒有加這句會造成內存泄露
    // Make the new assignment.
    _count = newCount; //單純的指針賦值
}

 

/***************************************/

The second uses a convenience constructor to create a new NSNumber object. There is therefore no need for retain or release messages

- (void)reset {
    NSNumber *zero = [NSNumber numberWithInteger:0];
    [self setCount:zero];
}
Note that both use the set accessor method.

The following will almost certainly work correctly for simple cases, but as tempting as it may be to eschew accessor methods, doing so will almost certainly lead to a mistake at some stage (for example, when you forget to retain or release, or if the memory management semantics for the instance variable change).

- (void)reset {
    NSNumber *zero = [[NSNumber alloc] initWithInteger:0];
    [_count release];
    _count = zero;
}
Note also that if you are using key-value observing, then changing the variable in this way is not KVO compliant.

/**********************************************************/

這是官方寫的一個reset 方法,簡單的說 alloc  出來的對象引用計數+1,所以在不需要的時候需要 release,

[NSNumber numberWithInteger:0];  這種方法引用計數沒有+1 ,因此再不需要的時候 ,也不需要release,

至于內部是如何實現,本文就不做研究了。

/************************************************************/

 

Don’t Use Accessor Methods in Initializer Methods and dealloc
The only places you shouldn’t use accessor methods to set an instance variable are in initializer methods and dealloc. To initialize a counter object with a number object representing zero, you might implement an init method as follows:

- init {
    self = [super init];
    if (self) {
        _count = [[NSNumber alloc] initWithInteger:0];
    }
    return self;
}

/************************************************************/

這個比較重要 ,類的初始化方法 中,不能實現類似 self.count 這樣的方法,這是因為 類似self.count =1;

個人理解是這樣的  init() 方法只有在返回的時候該類才能說被完整的創建。

self.count 相當于 self.getcount();方法 由于 這個方法很有可能被重載了,而導致結果難以預料。  //*注 :如有錯誤歡迎指正

不管如何這個都應該成為我們的設計準則。

/************************************************************/

Use Weak References to Avoid Retain Cycles

Retaining an object creates a strong reference to that object. An object cannot be deallocated until all of its strong references are released. A problem, known as a retain cycle, can therefore arise if two objects may have cyclical references—that is, they have a strong reference to each other (either directly, or through a chain of other objects each with a strong reference to the next leading back to the first).

The object relationships shown in Figure 1 illustrate a potential retain cycle. The Document object has a Page object for each page in the document. Each Page object has a property that keeps track of which document it is in. If the Document object has a strong reference to the Page object and the Page object has a strong reference to the Document object, neither object can ever be deallocated. The Document’s reference count cannot become zero until the Page object is released, and the Page object won’t be released until the Document object is deallocated.

The solution to the problem of retain cycles is to use weak references. A weak reference is a non-owning relationship where the source object does not retain the object to which it has a reference.

To keep the object graph intact, however, there must be strong references somewhere (if there were only weak references, then the pages and paragraphs might not have any owners and so would be deallocated). Cocoa establishes a convention, therefore, that a “parent” object should maintain strong references to its “children,” and that the children should have weak references to their parents.

So, in Figure 1 the document object has a strong reference to (retains) its page objects, but the page object has a weak reference to (does not retain) the document object.

Examples of weak references in Cocoa include, but are not restricted to, table data sources, outline view items, notification observers, and miscellaneous targets and delegates.

You need to be careful about sending messages to objects for which you hold only a weak reference. If you send a message to an object after it has been deallocated, your application will crash. You must have well-defined conditions for when the object is valid. In most cases, the weak-referenced object is aware of the other object’s weak reference to it, as is the case for circular references, and is responsible for notifying the other object when it deallocates. For example, when you register an object with a notification center, the notification center stores a weak reference to the object and sends messages to it when the appropriate notifications are posted. When the object is deallocated, you need to unregister it with the notification center to prevent the notification center from sending any further messages to the object, which no longer exists. Likewise, when a delegate object is deallocated, you need to remove the delegate link by sending a setDelegate: message with a nil argument to the other object. These messages are normally sent from the object’s dealloc method.

/************************************************************/

簡單的解釋下 ,想必大家都對retain,assign,weak,strong這些有所理解,但是什么時候使用什么引用呢?

首先官方文檔說明了一種情況 ,就是在 A 引用 B ,B引用C的情況下,這樣就形成了一個閉環,造成內存無法被釋放掉,這個時候怎么辦?

官方的解決方法是采用 weak和strong 來解決它,只有根部的屬性采用strong 描述,weak 用于描述子的屬性,這樣就能解決循環引用問題。 簡單的說 strong 屬性會令引用計數+1,而weak則不會,這樣就不會造成循環引用。

/**************************************************************/

Ownership Policy Is Implemented Using Retain Counts

The ownership policy is implemented through reference counting—typically called “retain count” after the retain method. Each object has a retain count.

When you create an object, it has a retain count of 1.
When you send an object a retain message, its retain count is incremented by 1.
When you send an object a release message, its retain count is decremented by 1.
When you send an object a autorelease message, its retain count is decremented by 1 at the end of the current autorelease pool block.

If an object’s retain count is reduced to zero, it is deallocated.

Important: There should be no reason to explicitly ask an object what its retain count is (see retainCount). The result is often misleading, as you may be unaware of what framework objects have retained an object in which you are interested. In debugging memory management issues, you should be concerned only with ensuring that your code adheres to the ownership rules.

/**************************************************************/

這是引用計數設計的幾條原則,蘋果特意說明了只需要遵守這幾個準則就行了,任何試圖打印當前引用計數的方法,所得到的結果都可能是錯誤的。

其他的還有一些細節,就不再這里一一贅述了。

總結一下 :引用計數分為3類:

1.assign 

2.copy

3. retain  (其中包含 weak和strong 用于解決循環引用問題)

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美精品九九久久| 亚洲一区二区中文字幕| 久久成人精品一区二区三区| 中文字幕亚洲情99在线| 欧美一级片在线播放| 国产乱人伦真实精品视频| 国产成人精品免费久久久久| 国内外成人免费激情在线视频| 日韩国产一区三区| 色狠狠av一区二区三区香蕉蜜桃| 亚洲第一二三四五区| 亚洲欧美日韩国产精品| 欧美精品aaa| 午夜精品视频在线| 国产玖玖精品视频| 中文字幕亚洲精品| 中文字幕免费国产精品| 欧美中文字幕在线| 中文字幕v亚洲ⅴv天堂| 国产精品96久久久久久又黄又硬| 久久视频在线播放| 91久久久久久久久久久| 国产精品一区二区女厕厕| 国产区亚洲区欧美区| 亚洲成色www8888| 日韩欧美在线看| 狠狠久久五月精品中文字幕| 亚洲视频综合网| 久久久久久这里只有精品| 日韩av电影手机在线| 日韩精品在线免费播放| 最新的欧美黄色| 国产日韩欧美自拍| 国产精品久久久久久久久久三级| 亚洲女人天堂av| 九九热这里只有精品6| 韩曰欧美视频免费观看| 亚洲一区二区精品| 亚洲第一免费网站| 欧美中文在线观看国产| 欧美激情乱人伦一区| 欧美日韩精品在线播放| 久久久久久久久久久成人| 日韩精品在线第一页| 高跟丝袜一区二区三区| 日本精品视频网站| 麻豆国产va免费精品高清在线| 日韩欧美在线视频| 国产精品狼人色视频一区| 日韩免费视频在线观看| 久久成人一区二区| 亚洲一区二区三区成人在线视频精品| 欧美成人四级hd版| 欧美日韩一区二区三区| 青青草99啪国产免费| 欧美激情精品在线| 国产成人精品a视频一区www| 亚洲精品乱码久久久久久按摩观| 91青草视频久久| 国产日韩在线精品av| 亚洲激情视频在线| 91视频-88av| 精品国产91久久久久久老师| xxx成人少妇69| 欧美交受高潮1| 欧美老少配视频| 亚洲另类欧美自拍| 日韩av最新在线| 亚洲最新av在线网站| 欧美怡红院视频一区二区三区| 中文字幕精品一区久久久久| 国产91在线视频| 国产亚洲视频在线观看| 亚洲国产精品网站| 日韩免费av片在线观看| 国产999精品| 亚洲精美色品网站| 成人免费看片视频| 亚洲精品之草原avav久久| 一区二区三区精品99久久| 亚洲欧洲美洲在线综合| 亚洲精品自拍第一页| 精品自在线视频| 久久亚洲精品一区二区| 亚洲自拍偷拍视频| 欧美午夜电影在线| 国产91精品黑色丝袜高跟鞋| 色黄久久久久久| 日韩在线观看免费高清| 欧美丰满片xxx777| 91久久久久久久一区二区| 亚洲一区二区中文字幕| 久久综合国产精品台湾中文娱乐网| 国产激情久久久久| 91av在线影院| 国产美女扒开尿口久久久| 欧美精品久久久久久久| 国产一区欧美二区三区| 97视频免费在线观看| 欧美国产日韩一区二区| 久久影视免费观看| 亚洲国产精品人久久电影| 91在线直播亚洲| 国产精品视频区| 亚洲国产另类 国产精品国产免费| 91高潮在线观看| 26uuu国产精品视频| 欧美成人亚洲成人日韩成人| 亚洲的天堂在线中文字幕| 欧美激情网站在线观看| 欧美在线视频在线播放完整版免费观看| **欧美日韩vr在线| 中文字幕亚洲欧美一区二区三区| 久久久综合免费视频| 欧美黑人一级爽快片淫片高清| 亚洲欧洲在线看| 午夜精品一区二区三区av| 亚洲视频在线免费观看| 亚洲网站视频福利| 91九色精品视频| 国产999在线观看| 亚洲欧美视频在线| 国内精品400部情侣激情| 国产成人精品在线视频| 国产一区二区三区在线| 国产裸体写真av一区二区| 亚洲精品电影在线| 国产欧美婷婷中文| 91香蕉国产在线观看| 欧美极品少妇xxxxⅹ喷水| 影音先锋日韩有码| 欧美日韩在线另类| 精品视频中文字幕| 久久久天堂国产精品女人| 九九热这里只有精品6| 欧美性猛交xxxx富婆弯腰| 色狠狠av一区二区三区香蕉蜜桃| 亚洲国产精品99久久| 91理论片午午论夜理片久久| 欧美午夜激情小视频| 亚洲激情小视频| 日韩人在线观看| 亚洲国产精彩中文乱码av| 日韩av在线网| 亚洲午夜久久久久久久| 91性高湖久久久久久久久_久久99| 色偷偷偷综合中文字幕;dd| 国产精品久久二区| 91精品国产91久久久| 中文字幕日韩专区| 日本欧美中文字幕| 另类专区欧美制服同性| 疯狂做受xxxx欧美肥白少妇| 国产精品久久久久久超碰| 国产精品成人免费电影| 欧美中文字幕在线观看| 亚洲国产精品成人av| 亚洲色图欧美制服丝袜另类第一页| 国产精自产拍久久久久久蜜| 97国产在线观看| 亚洲xxx自由成熟| 国产一区二区三区精品久久久| 亚洲激情中文字幕| 91免费观看网站|