iOS 属性关键字

几个iOS的属性关键字

1.nonatomic、atomiac:
nonatomic:非原子的, atomiac 原子的 。属性默认是 atomiac , 也就是原子性的。nonatomic执行效率高。
atomiac:读写安全,但效率低,不是绝对的安全。
2.readwrite、readonly:
readwrite 读写,readonly 只读。 属性默认是 readwrite , 支持读写。
readwirte: 属性同时具有 set 和 get 方法。
readonly: 属性只具有 get 方法。
3.assign:
既可以修饰基本数据类型,也可以修饰对象类型; setter 方法的实现是直接赋值,一般用于基本数据类型 ;修饰基本数据类型,如 NSInteger、BOOL、int、float 等;修饰对象类型时,不增加其引用计数;会产生悬垂指针(悬垂指针:assign 修饰的对象在被释放之后,指针仍然指向原对象地址,该指针变为悬垂指针。这时候如果继续通过该指针访问原对象的话,就可能导致程序崩溃)。

strong

strong 是对象的默认属性关键字,此特质表明该属性定义了一种“持有关系”,为这种属性设置新值时,设置方法既会先保留新值,并释放旧值,然后再将新值设置上去。此时与原对象指向的是同一地址。当原对象为可变对象时,将原对象赋给strong修饰的不可变对象,修改原对象,那我们不可变的对象也会随之改变

copy

此特质所表达的所属关系与strong类似,然后设置方法并不保留(retain)新值,而是将其复制(copy)。copy修饰不可变对象,strong修饰可变对象。

  • copy修饰不可变对象、原对象为不可变对象时,将原对象赋值给属性,会将原对象进行copy,此时是浅复制,两个指针指向的是同一个地址。
  • copy修饰不可变对象,原对象为可变对象时,将原对象赋值给属性,会将原对象进行copy,此时是深复制,两个对象指向的不同的地址,属性所指的是可变对象的副本,原对象如果被修改的话,不会影响属性的值。
  • copy修饰可变对象,如果原对象是不可变对象并赋值给属性,那么进行的是浅复制,指向同一地址。
  • copy修饰可变对象,如果原对象是可变对象并赋值给属性,此时进行的是深复制,属性指向的是原对象的不可变副本,即此时属性为不可变对象,这时对属性进行增删改的操作,就会因为找不到方法而报错。

示例:

#import <Foundation/Foundation.h>

@interface test : NSObject

@property (nonatomic, copy) NSString *stringCopy;

@property (nonatomic, strong) NSString *stringStrong;

@property (nonatomic, copy) NSMutableString *mutableStringCopy;

@end
//  main.m
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        test * test1 = [[test alloc] init];
        
        NSString *string = @"222";
        
        test1.stringCopy = string;
        test1.stringStrong = string;
        NSLog(@"%p %p %p", string, test1.stringCopy, test1.stringStrong);
        
        NSMutableString *string2 = [[NSMutableString alloc] initWithString:@"111"];
        test1.stringCopy = string2;
        test1.stringStrong = string2;
        NSLog(@"%p %p %p", string2, test1.stringCopy, test1.stringStrong);
        
        [string2 appendString:string];
        NSLog(@"%@ %@ %@", string2, test1.stringCopy, test1.stringStrong);
    }
    return 0;
}

通过程序来实际看一下到底有什么区别。
输出结果:

0x100004008 0x100004008 0x100004008
0x1005229a0 0x84e16ab6357c8f7c 0x1005229a0
111222 111 111222

在赋值类型为NSMutableString时,因为对NSMutableString 执行copy方法是深拷贝 ,开辟了新的内存,所以copy修饰的属性内存地址变了,而strong只是引用计数+1,内存地址还是源字符串的,所以改变影响不到copy修饰的属性,而会改变strong修饰的属性。当源字符串是不可变类型时,copy、strong改变源字符串,效果一样;当源字符串是可变类型时,copy 修饰的是深拷贝,改变源字符串,不影响copy的属性内容;strong修饰的属性,就随着源字符串的改变而变了。
对NSMutableString类型的变量使用copy,如:

@property (nonatomic, copy) NSMutableString *mutableStringCopy;

进行如下操作:

test1.mutableStringCopy = string2;
[test1.mutableStringCopy appendString:@"222"];

程序会崩溃,报错:

'-[NSTaggedPointerString appendString:]: unrecognized selector sent to instance 0xb04010f44c5ef9bd'

这是因为赋值时得到的对象是不可变对象,不可变对象肯定不会存在可变类型的方法。可以在我的另一篇博客中看一看有关内容:OC Foundation框架 对象复制

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值