oc属性关键字整理

2017-07-11  本文已影响54人  骑毛驴的小强

看面试题的经常看到一些关于关键字的问题,在oc中修饰一个属性一般有4种关键词

原子性--- atomic/nonatomic。(默认atomic) atomic在setter/getter方法里加了锁,多线程情况下,一个线程进行setter操作,另外一个线程就需要等待上一个线程setter操作完毕才能操作。避免多线程下同时对一个属性进行setter或者getter操作造成数据混乱。但是可以一个线程进行setter另外一个线程进行getter操作,还是会造成数据混乱,并不能真正的保证线程安全,比如下面的代码

@property (atomic, assign) int leftTicketCount;

self.leftTicketCount = 50;
self.thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
self.thread1.name = @"1号窗口";

self.thread2 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
self.thread2.name = @"2号窗口";

self.thread3 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
self.thread3.name = @"3号窗口";

[self.thread1 start];
[self.thread2 start];
[self.thread3 start];
- (void)saleTicket
{

   while (1) {
       NSUInteger count = self.leftTicketCount;
       if (count > 0) {
           self.leftTicketCount = count - 1;
           NSLog(@"%@卖了一张票, 剩余%zd张票", [NSThread currentThread].name, self.leftTicketCount);
       } else {
           return; // 退出循环
       }
   }
}
2017-06-21 12:38:45.727 [14137:733573] 1号窗口卖了一张票, 剩余32张票
2017-06-21 12:38:45.727 [14137:733574] 2号窗口卖了一张票, 剩余31张票
2017-06-21 12:38:45.832 [14137:733573] 1号窗口卖了一张票, 剩余29张票
2017-06-21 12:38:45.832 [14137:733575] 3号窗口卖了一张票, 剩余30张票

atomic并不能保证线程安全,只是保证了setter/getter的操作安全(同一时间多条线程不能同时操作setter或者getter)。想要安全还得加锁。

- (void)saleTicket
{

    while (1) {

        @synchronized(self) { // 开始加锁
            NSUInteger count = self.leftTicketCount;
            if (count > 0) {
                self.leftTicketCount = count - 1;
                NSLog(@"%@卖了一张票, 剩余%zd张票", [NSThread currentThread].name, self.leftTicketCount);
            } else {
                return; // 退出循环
            }
        } // 解锁
    }
}

读/写权限(默认readwrite)---readwrite(读写)、readonly (只读)
但是readonly真的就不能被外界修改了吗? 没有什么是KVC不能修改的
内存管理语义---assign、strong、 weak、unsafe_unretained、copy

assign:适用于非OC对象,比较说一些基本数据类型
strong:适用于OC对象,需要对属性进行强引用
weak:适用于OC对象,弱引用,强调“非拥有”的关系,比如delegate属性
copy:copy修饰的属性的值是不可变的,相当于值引用,strong相当于地址引用。
   用copy修饰一个属性
   @property (nonatomic , copy) NSArray *array;

    //执行下面代码
    NSArray *tempArr = @[ @1, @2, @3, @4 ];
    NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:tempArr];
    self.array = mutableArray;
    [mutableArray removeAllObjects];;
    NSLog(@"%@,%@",self.array,mutableArray);

输出

2017-06-21 13:54:58.765 循环引用[14684:849540] (
    1,
    2,
    3,
    4
),(
)
将array的copy修饰词改成strong,打印结果如下
2017-06-21 13:54:58.765 循环引用[14684:849540] (
),(
)

strong会引用mutableArray的地址给array,mutableArray释
放了,array也就释放了,但是copy是拷贝的值。

copy修饰的可变类型的属性,底层都会变成不可变类型

@property (nonatomic , copy) NSMutableArray *mutableArray;

执行下面代码:
self.mutableArray = [NSMutableArray arrayWithObjects:@3,@2,nil];
    [self.mutableArray removeObjectAtIndex:0];
直接报错
erminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI removeObjectAtIndex:]: unrecognized selector sent to instance 0x60000023e180'
__NSArrayI表示self.mutableArray是不可变数组。

方法名---getter=<name> 、setter=<name> 起别名

上一篇 下一篇

猜你喜欢

热点阅读