數(shù)組或字典如何弱引用對(duì)象

前言

將一個(gè)對(duì)象添加到一個(gè)array或dictornary里一件很常見的事,一般不會(huì)遇到問題。但是如果這個(gè)容器會(huì)一直存在的靜態(tài)全局對(duì)象時(shí),就會(huì)影響object的釋放,造成內(nèi)存泄露。起初已為定義一個(gè)__weak object,然后把它作為參數(shù)就可以,太異想天開了,這種仍然會(huì)strong引用。

主要的解決方法有三種:

1.NSValue
可以使用的 valueWithNonretainedObject:view方法來弱引用一個(gè)對(duì)象

        NSValue *key = [NSValue valueWithNonretainedObject:view];
        [dic setObject:outlineView forKey:key];

2.NSMapTable, NSPointerArray,NSHashTable

NSMapTable有兩個(gè)初始化的方法

- (instancetype)initWithKeyOptions:(NSPointerFunctionsOptions)keyOptions valueOptions:(NSPointerFunctionsOptions)valueOptions capacity:(NSUInteger)initialCapacity NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithKeyPointerFunctions:(NSPointerFunctions *)keyFunctions valuePointerFunctions:(NSPointerFunctions *)valueFunctions capacity:(NSUInteger)initialCapacity NS_DESIGNATED_INITIALIZER;

NSPointerFunctionsOptions 是內(nèi)存管理策略的枚舉值,主要有NSPointerFunctionsWeakMemory,NSPointerFunctionsStrongMemory兩個(gè)值,代表弱引用和強(qiáng)引用。而NSPointerFunctionsWeakMemory就是我們想要的。不僅如此,NSMapTable的key和value都可以分別設(shè)置弱引用或強(qiáng)引用,非常強(qiáng)大。
如果弱引用的對(duì)象被釋放了會(huì)怎么樣?
如果key對(duì)象被釋放, key=nil,那么key和value都會(huì)被移除,至少遍歷的時(shí)候不會(huì)遍歷掉。
如果value對(duì)象被釋放,那么key存在,value=nil

我們將Key和value都弱引用,示例如下:

_table = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsWeakMemory valueOptions:NSPointerFunctionsWeakMemory capacity:4];
    [_table setObject:[UIView new] forKey:@"weakKey"];
    [_table setObject:self.view forKey:@"strongKey"];

NSPointerArray
它的初始化跟NSMapTable非常相似,它是一個(gè)可變的、可插入null的數(shù)組,可以設(shè)置弱引用
NSHashTable
類似于NSMutableSet,支持弱引用,可變的、可插入null的set

NSFastEnumeration協(xié)議

我們經(jīng)常發(fā)現(xiàn)集合類都實(shí)現(xiàn)了NSFastEnumeration這個(gè)協(xié)議,像NSArray,NSDictionary, NSMapTable, NSHashTable等等。
協(xié)議的定義:

@protocol NSFastEnumeration

- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id __unsafe_unretained _Nullable [_Nonnull])buffer count:(NSUInteger)len;

@end

實(shí)現(xiàn)NSFastEnumeration這個(gè)協(xié)議,就會(huì)支持for/in語法糖,但并不代表會(huì)有enumerateObjectsUsingBlock方法,這個(gè)方法是NSArray自己定義實(shí)現(xiàn)的。還有當(dāng)自定義類實(shí)現(xiàn)countByEnumeratingWithState方法時(shí),要根據(jù)不同的數(shù)組存儲(chǔ)類型選擇適合自己的一套算法實(shí)現(xiàn),這里其實(shí)并沒有固定算法。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容