objc_setAssociatedObjec

本博客详细介绍了如何在iOS应用中通过按钮触发显示提示框,并在提示框中关联按钮实例,实现数据传递与展示。通过设置关联对象,实现了按钮与提示信息之间的互动,展示了iOS开发中对象关联与数据传递的实用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//唯一静态变量key

static const char associatedkey;

static const char associatedButtonkey;


- (IBAction)sendAlert:(UIButton*)sender

{

    

    NSString *message =@"我知道你是按钮了";

    

    UIAlertView *alert = [[UIAlertViewalloc]initWithTitle:@"提示"message:@"我要传值·" delegate:selfcancelButtonTitle:@"确定" otherButtonTitles:nil];

    alert.delegate =self;

    [alert show];


     //#import <objc/runtime.h>头文件

     //objc_setAssociatedObject需要四个参数:源对象,关键字,关联的对象和一个关联策略。


     //1 源对象alert

    //2 关键字 唯一静态变量key associatedkey

    //3 关联的对象 sender

    //4 关键策略  OBJC_ASSOCIATION_RETAIN_NONATOMIC

    

    

    objc_setAssociatedObject(alert, &associatedkey, message,OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    

    objc_setAssociatedObject(alert, &associatedButtonkey, sender,OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    

}

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

{

    

    

    //通过 objc_getAssociatedObject获取关联对象

    NSString  *messageString =objc_getAssociatedObject(alertView, &associatedkey);

    

    

    UIButton *sender = objc_getAssociatedObject(alertView, &associatedButtonkey);

    

    _labebutton.text = [[sendertitleLabel]text];

    _ThisLabel.text = messageString;

    

    

    //使用函数objc_removeAssociatedObjects可以断开所有关联。通常情况下不建议使用这个函数,因为他会断开所有关联。只有在需要把对象恢复到原始状态的时候才会使用这个函数。

}

<think>好的,我需要回答用户关于iOS开发中OBJC_ASSOCIATION_RETAIN_NONATOMIC和OBJC_ASSOCIATION_COPY_NONATOMIC的区别及适用场景的问题。首先,我需要回顾一下相关的Objective-C运行时函数objc_setAssociatedObject的作用,以及不同的关联策略。 根据用户提供的引用内容,特别是引用3,里面详细说明了这两种策略的等价属性和行为。OBJC_ASSOCIATION_RETAIN_NONATOMIC相当于@property(strong, nonatomic),也就是对关联对象进行强引用,非原子性。而OBJC_ASSOCIATION_COPY_NONATOMIC则相当于@property(copy, nonatomic),这意味着关联的对象会被复制,并且同样是非原子性的。 接下来,我需要明确它们的区别。首先,RETAIN会保留对象,增加其引用计数,而COPY则会创建对象的副本。这对于可变和不可变对象尤其重要。例如,如果关联的对象是NSMutableString类型,使用COPY策略会生成一个不可变的NSString副本,防止外部修改影响关联的值。而RETAIN则直接持有原对象,如果原对象被修改,关联的值也会随之改变。 适用场景方面,当需要确保关联对象的值不被意外修改时,应该使用COPY,尤其是当对象本身有可变子类的时候。例如,NSString、NSArray等不可变类型,使用COPY可以防止传入的可变对象在后续被修改。而RETAIN适用于需要共享同一对象实例的情况,或者对象本身不可变,不需要担心被修改的情况。 另外,需要注意非原子性(nonatomic)的影响,这意味着不会生成线程安全的访问方法,适合在不需要考虑多线程安全的环境下使用,以提高性能。 还需要确认是否有其他相关的策略,比如原子性版本或其他类型,但根据用户的问题,主要集中在RETAIN和COPY的非原子版本上。同时,引用2和4也提到关联对象常用于分类中添加属性,或者绑定block回调,这时候选择合适的策略非常重要,比如block通常需要COPY来确保其存储在堆上。 最后,要确保回答结构清晰,分点说明区别和使用场景,并给出示例,帮助用户理解不同策略的选择依据。</think>在iOS开发中,`OBJC_ASSOCIATION_RETAIN_NONATOMIC`和`OBJC_ASSOCIATION_COPY_NONATOMIC`是两种不同的**关联策略**,用于`objc_setAssociatedObject`函数中动态为对象添加属性。它们的核心区别在于**内存管理语义**和**适用场景**。 --- ### 一、区别分析 #### 1. `OBJC_ASSOCIATION_RETAIN_NONATOMIC` - **语义**:等价于`@property(strong, nonatomic)`,即对关联对象进行**强引用**且非原子操作。 - **行为**: - 对关联对象调用`retain`,增加其引用计数。 - **非线程安全**(`nonatomic`),但性能更高。 - **示例**: ```objective-c objc_setAssociatedObject(obj, &key, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC); ``` #### 2. `OBJC_ASSOCIATION_COPY_NONATOMIC` - **语义**:等价于`@property(copy, nonatomic)`,即对关联对象调用`copy`方法生成新对象,并**非原子性**持有。 - **行为**: - 对关联对象调用`copy`,生成不可变副本(若对象遵守`NSCopying`协议)。 - 同样**非线程安全**。 - **示例**: ```objective-c objc_setAssociatedObject(obj, &key, value, OBJC_ASSOCIATION_COPY_NONATOMIC); ``` --- ### 二、关键差异 | 特性 | RETAIN_NONATOMIC | COPY_NONATOMIC | |---------------------|-----------------------------------------|-----------------------------------------| | **内存管理** | 强引用原对象 | 创建原对象的拷贝 | | **对象可变性影响** | 原对象修改会影响关联值 | 原对象修改不影响关联的拷贝 | | **适用对象类型** | 需共享实例的场景(如UI控件、单例) | 需保护值不被意外修改(如NSString、NSArray) | --- ### 三、使用场景 #### 1. `OBJC_ASSOCIATION_RETAIN_NONATOMIC`适用场景 - **需要持有对象实例**:例如关联一个`UIView`控件或自定义模型对象。 - **对象本身不可变**:如已确定关联的`NSArray`不会被外部修改。 - **性能敏感场景**:避免`copy`操作的开销。 #### 2. `OBJC_ASSOCIATION_COPY_NONATOMIC`适用场景 - **保护关联值不变**:例如关联`NSString`或`NSURL`,防止外部传入`NSMutableString`后被修改[^3]。 - **关联Block**:Block需通过`copy`存储到堆中(MRC环境下必需,ARC下自动处理)。 - **关联值类型为可变对象**:如传入`NSMutableArray`时,通过`copy`生成不可变版本。 --- ### 四、示例对比 假设关联一个`NSMutableString`: ```objective-c NSMutableString *mutableStr = [NSMutableString stringWithString:@"Hello"]; // 使用RETAIN_NONATOMIC objc_setAssociatedObject(obj, &key, mutableStr, OBJC_ASSOCIATION_RETAIN_NONATOMIC); [mutableStr appendString:@" World"]; // 关联值会同步变为"Hello World" // 使用COPY_NONATOMIC objc_setAssociatedObject(obj, &key, mutableStr, OBJC_ASSOCIATION_COPY_NONATOMIC); [mutableStr appendString:@" World"]; // 关联值仍为"Hello" ``` --- ### 五、注意事项 1. **线程安全**:两者均为`nonatomic`,需自行保证多线程安全。 2. **循环引用**:若关联对象持有当前对象,需通过`OBJC_ASSOCIATION_ASSIGN`打破循环(如Delegate模式)[^4]。 3. **对象类型**:`COPY`要求对象实现`NSCopying`协议,否则会导致崩溃。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值