看面試題的經(jīng)澄獬看到一些關(guān)于關(guān)鍵字的問題,在oc中修飾一個屬性一般有4種關(guān)鍵詞
原子性--- atomic/nonatomic沫浆。(默認atomic) atomic在setter/getter方法里加了鎖眠冈,多線程情況下,一個線程進行setter操作贩猎,另外一個線程就需要等待上一個線程setter操作完畢才能操作。避免多線程下同時對一個屬性進行setter或者getter操作造成數(shù)據(jù)混亂瓤球。但是可以一個線程進行setter另外一個線程進行g(shù)etter操作融欧,還是會造成數(shù)據(jù)混亂,并不能真正的保證線程安全卦羡,比如下面的代碼
@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; // 退出循環(huán)
}
}
}
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; // 退出循環(huán)
}
} // 解鎖
}
}
讀/寫權(quán)限(默認readwrite)---readwrite(讀寫)欠肾、readonly (只讀)
但是readonly真的就不能被外界修改了嗎? 沒有什么是KVC不能修改的
內(nèi)存管理語義---assign拟赊、strong刺桃、 weak、unsafe_unretained吸祟、copy
assign:適用于非OC對象瑟慈,比較說一些基本數(shù)據(jù)類型
strong:適用于OC對象桃移,需要對屬性進行強引用
weak:適用于OC對象,弱引用葛碧,強調(diào)“非擁有”的關(guān)系借杰,比如delegate屬性
copy:copy修飾的屬性的值是不可變的,相當于值引用进泼,strong相當于地址引用蔗衡。
用copy修飾一個屬性
@property (nonatomic , copy) NSArray *array;
//執(zhí)行下面代碼
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 循環(huán)引用[14684:849540] (
1,
2,
3,
4
),(
)
將array的copy修飾詞改成strong,打印結(jié)果如下
2017-06-21 13:54:58.765 循環(huán)引用[14684:849540] (
),(
)
strong會引用mutableArray的地址給array乳绕,mutableArray釋
放了绞惦,array也就釋放了,但是copy是拷貝的值洋措。
copy修飾的可變類型的屬性济蝉,底層都會變成不可變類型
@property (nonatomic , copy) NSMutableArray *mutableArray;
執(zhí)行下面代碼:
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是不可變數(shù)組。
方法名---getter=<name> 呻纹、setter=<name> 起別名