国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【iOS分類、關(guān)聯(lián)對(duì)象】如何使用關(guān)聯(lián)對(duì)象給分類實(shí)現(xiàn)一個(gè)weak的屬性

這篇具有很好參考價(jià)值的文章主要介紹了【iOS分類、關(guān)聯(lián)對(duì)象】如何使用關(guān)聯(lián)對(duì)象給分類實(shí)現(xiàn)一個(gè)weak的屬性。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

如何使用關(guān)聯(lián)對(duì)象給分類實(shí)現(xiàn)一個(gè)weak的屬性

通過(guò)關(guān)聯(lián)對(duì)象objc_setAssociatedObject中的策略policy可知,并不支持使用weak修飾對(duì)象屬性:

typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
    OBJC_ASSOCIATION_ASSIGN = 0, //assign
    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, //strong, nonatomic
    OBJC_ASSOCIATION_COPY_NONATOMIC = 3, //copy, nonatomic
    OBJC_ASSOCIATION_RETAIN = 01401, //strong, atomic
    OBJC_ASSOCIATION_COPY = 01403 //copy, atomic
};

思考:能否用assign實(shí)現(xiàn)?

weak和assign的區(qū)別如下:

  • **assign:**對(duì)應(yīng)的所有權(quán)類型為_(kāi)_unsafe_unretained,當(dāng)修飾對(duì)象的時(shí)候,修飾的指針指向該對(duì)象,不會(huì)去持有該對(duì)象,也不會(huì)使retainCount +1,而在指向的對(duì)象被釋放時(shí),依然指向原來(lái)的對(duì)象地址,不會(huì)被自動(dòng)置為nil,所以造成了野指針,是不安全的;
  • **weak:**弱引用,不會(huì)影響對(duì)象的釋放,而當(dāng)對(duì)象被釋放時(shí)(引用計(jì)數(shù)為0),所有指向它的弱引用都會(huì)自定被置為nil,防止野指針,之后再向該對(duì)象發(fā)消息也不會(huì)崩潰,weak是安全的;

看以下測(cè)試代碼,使用policy為OBJC_ASSOCIATION_ASSIGN的策略,會(huì)發(fā)生什么樣的情況?

//定義Person類
@interface Person : NSObject
@end
@implementation Person
- (void)dealloc {
    NSLog(@"Person dealloc");
}
@end


@interface Person (Test)
//在分類中聲明UIViewController屬性,用assign修飾
@property(assign, nonatomic) UIViewController *viewController;
@end

@implementation Person (Test)
- (void)setViewController:(UIViewController *)viewController {
    //利用objc_setAssociatedObject設(shè)置值,policy為OBJC_ASSOCIATION_ASSIGN
    objc_setAssociatedObject(self, @selector(viewController), viewController, OBJC_ASSOCIATION_ASSIGN);
}
- (UIViewController *)viewController {//取值
    return objc_getAssociatedObject(self, _cmd);
}
@end

【iOS分類、關(guān)聯(lián)對(duì)象】如何使用關(guān)聯(lián)對(duì)象給分類實(shí)現(xiàn)一個(gè)weak的屬性,Objective-C,ios,分類,關(guān)聯(lián)對(duì)象

使用assign修飾對(duì)象,當(dāng)離開(kāi)作用域后,產(chǎn)生野指針訪問(wèn)Crash(如圖),如何避免這個(gè)問(wèn)題?

1、通過(guò)中間對(duì)象的方式

1.1、利用OBJC_ASSOCIATION_RETAIN_NONATOMIC + weak來(lái)實(shí)現(xiàn);

創(chuàng)建中間類:

@interface WeakObjWrapper : NSObject
@property(weak, nonatomic) id weakObj;
@end
@implementation WeakObjWrapper
- (instancetype)initWithWeakObject:(id)weakObj {
    if (self = [super init]) {
        _weakObj = weakObj;
    }
    return self;
}
@end

實(shí)現(xiàn)屬性的setter和getter:

@interface Person (Test)
@property(weak, nonatomic) UIViewController *viewController;
@end
@implementation Person (Test)
- (void)setViewController:(UIViewController *)viewController {
    WeakObjWrapper *warpper = objc_getAssociatedObject(self, @selector(viewController));
    //用warpper保存?zhèn)鬟f進(jìn)來(lái)的值
    if (!warpper) {//warpper不存在則創(chuàng)建
        warpper = [[WeakObjWrapper alloc] initWithWeakObject:viewController];
    }
    else {//已經(jīng)存在直接賦值
        warpper.weakObj = viewController;
    }
    //保存的實(shí)際上是warpper對(duì)象
    objc_setAssociatedObject(self, @selector(viewController), warpper, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIViewController *)viewController {
    //獲取到warpper
    WeakObjWrapper *warpper = objc_getAssociatedObject(self, _cmd);
    //取出warpper中的值
    return warpper.weakObj;
}
@end

objc_setAssociatedObject實(shí)際上存儲(chǔ)的是WeakObjWrapper對(duì)象,對(duì)WeakObjWrapper對(duì)象產(chǎn)生強(qiáng)引用,WeakObjWrapper對(duì)象內(nèi)部弱持有傳遞進(jìn)去的值,保證在對(duì)象釋放的時(shí)候,自動(dòng)把值設(shè)置為nil,避免了崩潰;

1.2、借助OBJC_ASSOCIATION_COPY_NONATOMIC和弱引用block

-(void)setWeakvalue:(NSObject *)weakvalue {
    __weak typeof(weakvalue) weakObj = weakvalue;
    typeof(weakvalue) (^block)() = ^(){
        return weakObj;
    };
    objc_setAssociatedObject(self, weakValueKey, block, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
-(NSObject *)weakvalue {
    id (^block)() = objc_getAssociatedObject(self, weakValueKey);
    return block();
}

2、借助runtime

繼續(xù)使用OBJC_ASSOCIATION_ASSIGN,利用runtime動(dòng)態(tài)的創(chuàng)建傳進(jìn)去值的類的子類,在子類的dealloc中,將objc_setAssociatedObject中的value設(shè)置為nil,銷毀并移除了關(guān)聯(lián)對(duì)象,避免Crash,具體實(shí)現(xiàn)如下(具體使用已在注釋中說(shuō)明):

void weak_setAssociatedObject(id _Nonnull object,
                              const void * _Nonnull key,
                              id _Nullable value) {
    //派生一個(gè)子類,類名為WeakObjWrapper+value對(duì)應(yīng)的類名
    const char *clsName = [[NSString stringWithFormat:@"WeakObjWrapper%@", [value class]] UTF8String];
    
    //獲取派生的子類
    Class childCls = objc_getClass(clsName);
    
    //如果子類不存在,利用runtime動(dòng)態(tài)的創(chuàng)建一個(gè)子類
    if (!childCls) {
        childCls = objc_allocateClassPair([value class], clsName, 0);
        objc_registerClassPair(childCls);
    }
    //注冊(cè)dealloc方法SEL
    SEL sel = sel_registerName("dealloc");
    
    //獲取dealloc對(duì)應(yīng)的類型編碼
    const char *deallocEncoding = method_getTypeEncoding(class_getInstanceMethod([value class], sel));
    
    // 注意:內(nèi)部持有value此處需要弱引用處理一下
    __weak typeof(value) weakValue = value;
    
    // 創(chuàng)建一個(gè)指向在調(diào)用dealloc方法時(shí)調(diào)用指定block的函數(shù)指針
    IMP deallocImp = imp_implementationWithBlock(^(id _childCls) {
        //在子類的dealloc方法中將value設(shè)置為nil,避免崩潰
        objc_setAssociatedObject(object, key, nil, OBJC_ASSOCIATION_ASSIGN);
        //派生的子類的dealloc方法會(huì)被調(diào)用,父類的不再被調(diào)用,故在此處調(diào)用一下父類的
        ((void (*)(id, SEL))(void *)objc_msgSend)(weakValue, sel);
    });
    //給子類添加dealloc方法
    class_addMethod(childCls, sel, deallocImp, deallocEncoding);
    
    //將value對(duì)應(yīng)的isa指向子類
    object_setClass(value, childCls);
    
    //設(shè)置關(guān)聯(lián)對(duì)象
    objc_setAssociatedObject(object, key, value, OBJC_ASSOCIATION_ASSIGN);
}

注意:在派生的子類,添加的實(shí)現(xiàn)dealloc的方法中,重新調(diào)用一下父類的dealloc保證原有的類的釋放關(guān)系不被破壞;調(diào)用(實(shí)現(xiàn)屬性的getter和setter):

@interface Person (Test)
@property(assign, nonatomic) UIViewController *viewController;
@end
@implementation Person (Test)
- (void)setViewController:(UIViewController *)viewController {
    weak_setAssociatedObject(self, @selector(viewController), viewController);
}
- (UIViewController *)viewController {
    return objc_getAssociatedObject(self, _cmd);
}
@end

總結(jié)

關(guān)聯(lián)對(duì)象中如何實(shí)現(xiàn)weak屬性?

  • 關(guān)聯(lián)對(duì)象objc_setAssociatedObject中的策略policy可知,并不支持使用weak修飾對(duì)象屬性;
  • 可以借助中間類(OBJC_ASSOCIATION_RETAIN_NONATOMIC + weak)來(lái)實(shí)現(xiàn);
  • 也可以繼續(xù)使用OBJC_ASSOCIATION_ASSIGN,利用runtime動(dòng)態(tài)的創(chuàng)建傳進(jìn)去值的類的子類,在子類的dealloc中,將objc_setAssociatedObject中的value設(shè)置為nil,銷毀并移除了關(guān)聯(lián)對(duì)象,從而避免了Crash;

參考1:https://www.cnblogs.com/huangzs/p/14479408.html

參考2:https://developer.aliyun.com/article/1321927#:~:text=1%20關(guān)聯(lián)對(duì)象objc_setAssociatedObject中的策略policy可知,并不支持使用weak修飾對(duì)象屬性;%202%20可以借助中間類(OBJC_ASSOCIATION_RETAIN_NONATOMIC,%2B%20weak)來(lái)實(shí)現(xiàn);%203%20也可以繼續(xù)使用OBJC_ASSOCIATION_ASSIGN,利用runtime動(dòng)態(tài)的創(chuàng)建傳進(jìn)去值的類的子類,在子類的dealloc中,將objc_setAssociatedObject中的value設(shè)置為nil,銷毀并移除了關(guān)聯(lián)對(duì)象,從而避免了Crash;文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-833768.html

到了這里,關(guān)于【iOS分類、關(guān)聯(lián)對(duì)象】如何使用關(guān)聯(lián)對(duì)象給分類實(shí)現(xiàn)一個(gè)weak的屬性的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 面試題:如何知道java對(duì)象被垃圾回收掉,用代碼實(shí)現(xiàn)一個(gè)能監(jiān)聽(tīng)對(duì)象被回收的功能

    Java中無(wú)法直接判斷一個(gè)對(duì)象是否被垃圾回收掉,因?yàn)镴ava的垃圾回收機(jī)制是自動(dòng)的,程序員并不需要手動(dòng)清理對(duì)象。但是,如果我們想要知道一個(gè)對(duì)象何時(shí)被回收掉,可以使用 finalize() 方法。 每個(gè)Java對(duì)象都有一個(gè) finalize() 方法,這個(gè)方法會(huì)在對(duì)象被垃圾回收前調(diào)用一次。我們

    2024年02月02日
    瀏覽(34)
  • 【iOS】—— 屬性關(guān)鍵字及weak關(guān)鍵字底層原理

    【iOS】—— 屬性關(guān)鍵字及weak關(guān)鍵字底層原理

    參考博客:IOS開(kāi)發(fā)基礎(chǔ)——屬性(copy strong weak等) 內(nèi)存管理有關(guān)的: weak , assign , strong , retain , copy 線程安全有關(guān)的的: nonatomic , atomic 訪問(wèn)權(quán)限有關(guān)的的: readonly , readwrite (只讀,可讀寫) 修飾變量的: const , static , extern 這些

    2024年02月16日
    瀏覽(23)
  • 【NLP】一個(gè)使用PyTorch實(shí)現(xiàn)圖像分類的遷移學(xué)習(xí)實(shí)例

    在特征提取中,可以在預(yù)先訓(xùn)練好的網(wǎng)絡(luò)結(jié)構(gòu)后修改或添加一個(gè)簡(jiǎn)單的分類器,然后將源任務(wù)上預(yù)先訓(xùn)練好的網(wǎng)絡(luò)作為另一個(gè)目標(biāo)任務(wù)的特征提取器,只對(duì)最后增加的分類器參數(shù)重新學(xué)習(xí),而預(yù)先訓(xùn)練好的網(wǎng)絡(luò)參數(shù)不被修改或凍結(jié)。 在完成新任務(wù)的特征提取時(shí)使用的是源任務(wù)

    2024年02月14日
    瀏覽(13)
  • 實(shí)操-rapidminer進(jìn)行關(guān)聯(lián)分析、分類預(yù)測(cè)(使用相關(guān)算子,全流程講解)

    實(shí)操-rapidminer進(jìn)行關(guān)聯(lián)分析、分類預(yù)測(cè)(使用相關(guān)算子,全流程講解)

    目錄 一、關(guān)聯(lián)分析 1.構(gòu)建過(guò)程 1.1導(dǎo)入數(shù)據(jù) 1.2檢查缺失值,異常值 1.3 約減數(shù)據(jù)集中屬性 2.對(duì)結(jié)果的評(píng)述 2.1 FP-Growth的支持度(Support)參數(shù)為0.95情況 2.2 不同min support對(duì)關(guān)聯(lián)規(guī)則結(jié)果的影響 2.3 不同min confidence對(duì)結(jié)果的影響 3.促銷政策 二、分類預(yù)測(cè) 1.對(duì)Titannic Unlabeld進(jìn)行預(yù)測(cè)

    2024年02月05日
    瀏覽(28)
  • 數(shù)據(jù)挖掘18大算法實(shí)現(xiàn)以及其他相關(guān)經(jīng)典DM算法:決策分類,聚類,鏈接挖掘,關(guān)聯(lián)挖掘,模式挖掘、圖算法,搜索算法等

    數(shù)據(jù)挖掘18大算法實(shí)現(xiàn)以及其他相關(guān)經(jīng)典DM算法:決策分類,聚類,鏈接挖掘,關(guān)聯(lián)挖掘,模式挖掘、圖算法,搜索算法等

    【機(jī)器學(xué)習(xí)入門與實(shí)踐】入門必看系列,含數(shù)據(jù)挖掘項(xiàng)目實(shí)戰(zhàn):模型融合、特征優(yōu)化、特征降維、探索性分析等,實(shí)戰(zhàn)帶你掌握機(jī)器學(xué)習(xí)數(shù)據(jù)挖掘 專欄詳細(xì)介紹:【機(jī)器學(xué)習(xí)入門與實(shí)踐】合集入門必看系列,含數(shù)據(jù)挖掘項(xiàng)目實(shí)戰(zhàn):數(shù)據(jù)融合、特征優(yōu)化、特征降維、探索性分析

    2024年02月09日
    瀏覽(51)
  • 【NI USRP】每一個(gè)USRP是如何命名的呢,和原廠Ettus型號(hào)有什么關(guān)聯(lián)呢?

    【NI USRP】每一個(gè)USRP是如何命名的呢,和原廠Ettus型號(hào)有什么關(guān)聯(lián)呢?

    詳細(xì)的硬件配置,非常有助于設(shè)備的選型。 如果您采購(gòu)了X310+子板,是可以將其轉(zhuǎn)化為對(duì)應(yīng)的USRP型號(hào)的設(shè)備。 Ettus NI-USRP 頻段 最大帶寬 通道 B200mini 無(wú) 70 MHZ - 6 GHZ 56 MHz 1X1 B200mini-i 無(wú) 70 MHZ - 6 GHZ 56 MHz 1X1 B205mini-i 無(wú) 70 MHZ - 6 GHZ 56 MHz 1X1 B200 NI-2900 70 MHZ - 6 GHZ 56 MHz 1X1 B210 NI-2901

    2024年02月16日
    瀏覽(12)
  • IOS系統(tǒng)mobileconfig的作用,mobileconfig文件如何使用,蘋果超級(jí)簽實(shí)現(xiàn)

    .mobileconfig是蘋果系統(tǒng)配置描述文件,目前常用于蘋果超級(jí)簽獲取設(shè)備UDID。 官方介紹: 配置描述?件是XML ?件,包含以下內(nèi)容:設(shè)備安全策略、VPN 配置信息、Wi-Fi 設(shè)置、APN 設(shè)置、Exchange帳戶設(shè)置、郵件設(shè)置以及允許 iPhone 和 iPod touch 與企業(yè)系統(tǒng)配合使?的證書。 “iPhone配置

    2024年02月11日
    瀏覽(19)
  • list對(duì)象中如何根據(jù)對(duì)象中某個(gè)屬性去重使用Java8流實(shí)現(xiàn)

    list對(duì)象中如何根據(jù)對(duì)象中某個(gè)屬性去重使用Java8流實(shí)現(xiàn)

    在 Java 8 的流操作中,可以使用 distinct 方法來(lái)對(duì)一個(gè)對(duì)象流進(jìn)行去重,但是默認(rèn)情況下它會(huì)使用對(duì)象的 equals() 方法來(lái)判斷重復(fù)。如果你希望根據(jù)對(duì)象的某個(gè)屬性進(jìn)行去重,則可以使用 distinct 方法結(jié)合 map 方法來(lái)實(shí)現(xiàn)。 下面是一個(gè)示例代碼,假設(shè)你有一個(gè) List 對(duì)象 list,其中包

    2024年02月11日
    瀏覽(131)
  • Jmeter用于接口測(cè)試中,關(guān)聯(lián)如何實(shí)現(xiàn)

    Jmeter用于接口測(cè)試中,關(guān)聯(lián)如何實(shí)現(xiàn)

    Jmeter用于接口測(cè)試時(shí),后一個(gè)接口經(jīng)常需要用到前一次接口返回的結(jié)果,應(yīng)該如何獲取前一次請(qǐng)求的結(jié)果值,應(yīng)用于后一個(gè)接口呢,拿一個(gè)登錄的例子來(lái)說(shuō)明如何獲取。 1、打開(kāi)jmeter, 使用的3.3的版本,新建一個(gè)測(cè)試計(jì)劃,在測(cè)試計(jì)劃里新建一個(gè)線程組,新建一個(gè)登錄的http請(qǐng)

    2024年02月04日
    瀏覽(33)
  • Java如何使用XMLBeans實(shí)現(xiàn)XML和Java對(duì)象的相互轉(zhuǎn)換

    原文和更多內(nèi)容:?Java如何使用XMLBeans實(shí)現(xiàn)XML和Java對(duì)象的相互轉(zhuǎn)換 (techdatafuture.com) 要使用XMLBeans實(shí)現(xiàn)XML和Java對(duì)象的相互轉(zhuǎn)換,可以按照以下步驟進(jìn)行操作: 1. 添加X(jué)MLBeans Maven依賴: dependency ? ? groupIdorg.apache.xmlbeans/groupId ? ? artifactIdxmlbeans/artifactId ? ? version3.1.0/version /depen

    2024年02月16日
    瀏覽(24)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包