最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

iOS常見的幾個(gè)修飾詞深入講解

 更新時(shí)間:2018年09月03日 15:05:08   作者:郡王丶千夜  
這篇文章主要給大家介紹了關(guān)于iOS常見的幾個(gè)修飾詞的相關(guān)資料,iOS修飾詞包括assign、weak、strong、retain、copy、nonatomic、atomic、readonly、readwrite,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言:

最近公司在擴(kuò)招,做為公司僅有的唯一一個(gè)首席iOS開發(fā)工程師(手動(dòng)滑稽),我不得不硬著頭皮上陣。

然后卻發(fā)現(xiàn)很多人的水平和年限嚴(yán)重不符,公司招的人都是3年+以上經(jīng)驗(yàn)的人,然而這些人中有一半連修飾詞的作用也說的模棱兩可,加上自己水平也不高,對(duì)以后的職業(yè)生涯產(chǎn)生了嚴(yán)重的危機(jī)感,遂決定以后每周希望能寫一篇有價(jià)值的文章,與君共勉,今天就說說iOS常見的幾個(gè)修飾詞。

一、readOnly,readWrite

readOnly:

根據(jù)字面意思,大家都很容易知道是“只讀”的意思,意味著只生成了getter方法,而沒有生成setter方法,如果這時(shí)候調(diào)用setter方法,會(huì)報(bào)一個(gè)Assignment to readonly property錯(cuò)誤

PS:這里順便說一下self.和_的區(qū)別

self.就是調(diào)用property自動(dòng)生成的getter和setter方法,而_則是直接去調(diào)用實(shí)例變量(property會(huì)自動(dòng)生成一個(gè)實(shí)例變量,如果你重寫了getter與setter方法,property自動(dòng)生成的實(shí)例變量就無效了,需要手動(dòng)去申明一個(gè)實(shí)例變量或者用@@synthesize).

回到正題,那么這意味著我們就完全沒辦法去修改readOnly的屬性了嗎?不然,如果你嘗試一下setValue:forKey:,你就會(huì)發(fā)現(xiàn)竟然改變成功了,amazing,讓我們來看看代碼:

@interface MyFirstClass : NSObject

@property (nonatomic, copy, readonly) NSString * string;

@end


#import "MyFirstClass.h"

@implementation MyFirstClass

- (instancetype) init{

 self = [super init];
 if (self) {
 _string = @"來改變我啊";
 }

 return self;
}

@end

- (void)viewDidLoad {

 [super viewDidLoad];

 MyFirstClass * class = [MyFirstClass new];
 NSLog(@"string === %@", class.string);
 [class setValue:@"改變了" forKey:NSStringFromSelector(@selector(string))];
 NSLog(@"string === %@", class.string);
}
Log如下:
2018-03-16 11:08:58.932303+0800 PropertyDesc[5681:445705] string === 來改變我啊
2018-03-16 11:08:58.932454+0800 PropertyDesc[5681:445705] string === 改變了

而如果這個(gè)時(shí)候在MyFirstClass里加入

@implementation MyFirstClass

- (instancetype) init{
 self = [super init];
 if (self) {
 _string = @"來改變我啊";
 }
 
 return self;
}

+ (BOOL) accessInstanceVariablesDirectly{
 return NO;
}

@end

在運(yùn)行,boom,系統(tǒng)會(huì)報(bào)以下錯(cuò)誤

2018-03-16 11:19:21.619747+0800 PropertyDesc[6016:478446] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<MyFirstClass 0x6040000088f0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key string.'

沒有找到當(dāng)前要賦值的屬性,那么accessInstanceVariablesDirectly究竟是什么呢,我們打開蘋果的官方文檔找到Key-Value Coding Programming Guide

在這里可以看到,如果這個(gè)方法設(shè)為YES,訪問器就會(huì)去尋找名稱為_<key>, _is<Key>, <key>, or is<Key>的成員變量,如果為NO,就會(huì)跳到第6步,第6步就會(huì)報(bào)[valueForUndefinedKey:]錯(cuò)誤。

總結(jié):

readOnly并不能完全保證只讀,我們可以通過KVC嘗試去修改其值。

PS:有興趣的小伙伴可以嘗試去修改別人的SDK,包括蘋果爸爸的

readWrite:

這個(gè)實(shí)在沒什么可說的,默認(rèn)的修飾詞就是readWrite,代表可讀可寫

二、nonatomic、atomic

我們先看一下官方文檔


蘋果官網(wǎng)對(duì)兩者的說法

atomic:

默認(rèn)的屬性修飾詞,按官方文檔上說即使從不同的線程通過getter或setter方法去訪問屬性也能完全的獲取到或設(shè)置值,從這里也可以看出,atomic并不是線程安全的,因?yàn)閍tomic只能保證通過setter和getter方法能獲取到一個(gè)完整的value,如果A線程在getter,B、C線程在setter,可能A獲取到的值是BC執(zhí)行之后的值,也可能是BC線程執(zhí)行完之前的值,也可能是B C線程任何一個(gè)線程執(zhí)行完的值。

因此atomic的偽代碼大概如下:

- (void)setString:(NSString *)string{
 @synchronized(self) {
 if (_string != string) {
  [_string release];//MRC
  _string = [string copy];
 }
 }
}

- (NSString *) string{
 @synchronized(self) {
 return _ string;
 }
}

nonatomic:

相對(duì)而言,通過nonatomic修飾的屬性,并沒有做鎖的操作,多線程同時(shí)進(jìn)行setter/getter操作,并不能保證得到一個(gè)完整的value,所以相對(duì)atomic來說nonatomic修飾的屬性訪問速度更快,而且平時(shí)對(duì)線程安全我們更傾向于使用信號(hào)量、NSLock和synchronized去控制線程安全,他們都能保證代碼塊的原子性,所以幾乎所有的屬性都用nonatomic去修飾。

三、assign、weak與strong

assign:

一般來說,我們都用assign去修飾OC的基本數(shù)據(jù)類型,but why?

因?yàn)閍ssign并不會(huì)使對(duì)象的引用計(jì)數(shù)加1,也就是說如果用assign去修飾一個(gè)對(duì)象,這個(gè)對(duì)象會(huì)立即被釋放,重要的是assgin在被釋放的時(shí)候是不會(huì)自動(dòng)置為nil,還是保留對(duì)象的指針地址,會(huì)形成野指針,這個(gè)時(shí)候向其發(fā)送消息就會(huì)崩潰,簡(jiǎn)單實(shí)驗(yàn)的代碼如下:

@interface MySecondClass : NSObject

@property (nonatomic, assign) NSMutableArray * array;

@end

- (void) testMethodTwo{
 MySecondClass * class = [[MySecondClass alloc] init];
 self.secondClass = class;
 self.secondClass.array = [NSMutableArray array];
 [self.secondClass.array addObject:@(0)];
}

在運(yùn)行到最后一步的時(shí)候程序會(huì)崩潰報(bào)EXC_BAD_ACCESS的錯(cuò)誤,如果打斷點(diǎn)的話會(huì)發(fā)現(xiàn)在執(zhí)行到這步的時(shí)候array還是有地址的。

weak:

如果把上面的代碼
@property (nonatomic, assign) NSMutableArray * array;換成
@property (nonatomic, weak) NSMutableArray * array;

.這個(gè)時(shí)候程序并不會(huì)崩潰,如果你打個(gè)斷點(diǎn)的話會(huì)發(fā)現(xiàn)array被自動(dòng)置為nil,而OC的特性使得像nil發(fā)送消息并不會(huì)崩潰,這就是weak和assgin最大的區(qū)別,此外weak必須用于修飾對(duì)象,這和他自動(dòng)置為nil相關(guān),如果強(qiáng)行使用weak修飾基本數(shù)據(jù)類型,編譯器會(huì)報(bào)一個(gè)大大的紅色錯(cuò)誤!

strong:

strong的作用和assign和weak恰恰相反,strong也是屬性默認(rèn)的修飾詞,代表著被修飾的對(duì)象引用計(jì)數(shù)+1

如果把上面的代碼
@property (nonatomic, assign) NSMutableArray * array;換成
@property (nonatomic, strong) NSMutableArray * array;

self.secondClass.array = [NSMutableArray array];

最后一句代碼可以解釋為[NSMutableArray array]創(chuàng)造了一個(gè)對(duì)象A,此時(shí)A的引用計(jì)數(shù)為1,self.secondClass.array做為對(duì)象B,把A賦值給B的時(shí)候,A的引用計(jì)數(shù)加1,此時(shí)A的引用計(jì)數(shù)為2,B指向了A,然后編譯器會(huì)自動(dòng)對(duì)A進(jìn)行釋放操作(因?yàn)槭蔷植孔兞?,A的引用計(jì)數(shù)-1。在擁有B的對(duì)象不釋放的時(shí)候,A的引用計(jì)數(shù)永遠(yuǎn)不可能為0,除非你手動(dòng)釋放或者把B指向一個(gè)新的對(duì)象,這樣A永遠(yuǎn)不會(huì)被釋放,這就是所謂的強(qiáng)引用。

weak和strong的區(qū)別:weak和strong不同的是 當(dāng)一個(gè)對(duì)象不再有strong類型的指針指向它的時(shí)候 它會(huì)被釋放 ,即使還有weak型指針指向它。一旦最后一個(gè)strong型指針離去 ,這個(gè)對(duì)象將被釋放,所有剩余的weak型指針都將被清除。

copy與retain:

  • copy其實(shí)是建立了一個(gè)相同的對(duì)象,而retain不是.
  • copy是內(nèi)容拷貝,retain是指針拷貝.
  • copy是內(nèi)容的拷貝 ,對(duì)于像NSString,的確是這樣,如果拷貝的是NSArray這時(shí)只是copy了指向array中相對(duì)應(yīng)元素的指針.這便是所謂的"淺復(fù)制".

atomic是Objc使用的一種線程保護(hù)技術(shù),基本上來講,是防止在寫未完成的時(shí)候被另外一個(gè)線程讀取,造成數(shù)據(jù)錯(cuò)誤。而這種機(jī)制是耗費(fèi)系統(tǒng)資源的,所以在iPhone這種小型設(shè)備上,如果沒有使用多線程間的通訊編程,那么nonatomic是一個(gè)非常好的選擇。

四、copy與mutableCopy

蘋果官網(wǎng)對(duì)對(duì)象拷貝的說法

在說copy與mutableCopy之前我們先看看官方文檔對(duì)深拷貝與淺拷貝的闡釋,如下

深拷貝:

對(duì)象拷貝 - 重新申請(qǐng)一片內(nèi)存保留這個(gè)對(duì)象,與原對(duì)象之間沒有半點(diǎn)關(guān)系。

淺拷貝:

指針拷貝 - 實(shí)際上相當(dāng)于引用計(jì)數(shù)+1,被拷貝的和拷貝的引用同一個(gè)對(duì)象。

接下來我們分兩個(gè)方面做測(cè)試:

1.對(duì)非集合類對(duì)象的copy操作,以NSString為例

對(duì)immutableObject做copy操作

 NSString * string = [NSString stringWithFormat:@"1"];
 NSString * copyString = [string copy];
 NSString * mutableCopyString = [string mutableCopy];
 NSLog(@"string:%p", string);
 NSLog(@"copyString:%p", copyString);
 NSLog(@"mutableCopyString:%p", mutableCopyString);

Log如下:

2018-03-19 15:51:38.785253+0800 PropertyDesc[10283:759804] string:0xa000000000000311
2018-03-19 15:51:38.785435+0800 PropertyDesc[10283:759804] copyString:0xa000000000000311
2018-03-19 15:51:38.785518+0800 PropertyDesc[10283:759804] mutableCopyString:0x608000055150

可以看出對(duì)string和copyString的地址是一樣的,而mutableCopyString則不同。

對(duì)mutableObject做copy操作

 NSMutableString * string = [NSMutableString stringWithFormat:@"1"];
 NSString * copyString = [string copy];
 NSString * mutableCopyString = [string mutableCopy];
 NSLog(@"string:%p - %@", string, string);
 NSLog(@"copyString:%p - %@", copyString, copyString);
 NSLog(@"mutableCopString:%p - %@", mutableCopyString, mutableCopyString);
 [string appendString:@",2"];
 NSLog(@"copyString:%p - %@", copyString, copyString);
 NSLog(@"mutableCopString:%p - %@", mutableCopyString, mutableCopyString);

Log如下:

2018-03-19 15:51:38.785670+0800 PropertyDesc[10283:759804] string:0x60400005a940 - 1
2018-03-19 15:51:38.785784+0800 PropertyDesc[10283:759804] copyString:0xa000000000000311 - 1
2018-03-19 15:51:38.785834+0800 PropertyDesc[10283:759804] copyString:0xa000000000000311 - 1
2018-03-19 15:51:38.785891+0800 PropertyDesc[10283:759804] mutableCopyString:0x60400005a910 - 1
2018-03-19 15:51:38.786037+0800 PropertyDesc[10283:759804] mutableCopyString:0x60400005a910 - 1

可以看出對(duì)string與copyString、mutableCopyString三者的地址都是不同的。

即使改變了原string的value,copyString與mutableCopystring也沒有改變,這與下文對(duì)集合類對(duì)象得出的結(jié)論正好相反。

結(jié)論:

對(duì) immutableObject進(jìn)行 copy 操作是指針拷貝,mutableCopy 操作時(shí)對(duì)象拷貝。

對(duì) mutable Object進(jìn)行 copy 和 mutableCopy 都是對(duì)象拷貝。簡(jiǎn)單的表格圖如下:

Object Handle Result
immutableObject copy 指針拷貝
immutableObject mutableCopy 深拷貝
mutableObject copy 深拷貝
mutableObject mutableCopy 深拷貝

2.對(duì)集合類對(duì)象的copy操作

對(duì)immutableObject做copy操作

 NSArray * array = [NSArray arrayWithObject:@"1"];
 NSArray * copyArry = [array copy];
 NSMutableArray * mutableCopyArray = [array mutableCopy];
 
 NSLog(@"array:%p", array);
 NSLog(@"copyArry:%p", copyArry);
 NSLog(@"mutableCopyArray:%p", mutableCopyArray);

Log如下

2018-03-19 15:51:38.786167+0800 PropertyDesc[10283:759804] array:0x6000000094c0
2018-03-19 15:51:38.786278+0800 PropertyDesc[10283:759804] copyArray:0x6000000094c0
2018-03-19 15:51:38.786385+0800 PropertyDesc[10283:759804] mutableCopyArray:0x600000240030

可以看出array與copyArray的地址是一樣的,而mutableCopyArray則不同。

對(duì)mutableObject做copy操作

 NSMutableString * string = [NSMutableString stringWithFormat:@"1"];
 NSMutableArray * array = [NSMutableArray arrayWithObject:string];
 NSArray * copyArry = [array copy];
 NSMutableArray * mutableCopyArray = [array mutableCopy];
 
 NSLog(@"array:%p", array);
 NSLog(@"copyArry:%p", copyArry);
 NSLog(@"mutableCopyArray:%p", mutableCopyArray);
 [array addObject:@"2"];
 [string appendString:@"1"];
 
 NSLog(@"array:%p - %@", array, array);
 NSLog(@"copyArry:%p - %@", copyArry, copyArry);
 NSLog(@"mutableCopArray:%p - %@", mutableCopyArray, mutableCopyArray);

Log如下

2018-03-26 13:36:38.786499+0800 PropertyDesc[10283:759804] array:0x600000240150
2018-03-26 13:36:38.786600+0800 PropertyDesc[10283:759804] copyArry:0x6000000095f0
2018-03-26 13:36:38.786698+0800 PropertyDesc[10283:759804] mutableCopyArray:0x6000002400f0
2018-03-26 13:36:38.786865+0800 PropertyDesc[10283:759804] array:0x600000240150 - (
    11,
    2
)
2018-03-26 13:36:38.787018+0800 PropertyDesc[10283:759804] copyArry:0x6000000095f0 - (
    11
)
2018-03-26 13:36:38.787142+0800 PropertyDesc[10283:759804] mutableCopyArray:0x6000002400f0 - (
    11
)

What??不管是copy還是mutableCopy我們可以看到當(dāng)我們修改了string的值后,數(shù)組中的值都變了,但是在 [array addObject:@"2"];的時(shí)候兩個(gè)復(fù)制出來的數(shù)組的對(duì)象并沒有變化?

這里我們要提到一個(gè)新概念 不完全深拷貝(也有人說是單層深拷貝 )------ 即雖然新開辟了內(nèi)存地址,但是存放在內(nèi)存上的值(也就是數(shù)組里的元素仍然指向原數(shù)組元素值,并沒有另外復(fù)制一份),所以說上文中的array和mutableCopArray類似于有一個(gè)或多個(gè)相交點(diǎn)的相交鏈表。

而且我們也可以看到不管是copy還是mutableCopy都是不完全深拷貝,三者的地址都是不一樣的。

結(jié)論:

對(duì)immutableObject做copy是指針拷貝,做mutableCopy是不完全深拷貝。

對(duì)mutableObject做copy或mutableCopy都是不完全深拷貝。

有趣的是,這與上文的結(jié)論有類似之處。簡(jiǎn)單的表格圖如下:

Object Handle Result
immutableObject copy 指針拷貝
immutableObject mutableCopy 不完全深拷貝
mutableObject copy 不完全深拷貝
mutableObject mutableCopy 不完全深拷貝

并且如果打個(gè)斷點(diǎn)可以發(fā)現(xiàn)對(duì)任何對(duì)象做copy操作返回的是一個(gè)不可變的對(duì)象,對(duì)任何對(duì)象做mutableCopy返回的是一個(gè)可變的對(duì)象(有興趣的請(qǐng)自行驗(yàn)證)。

五、是用copy還是strong?

通過上述對(duì)copy與strong的描述,copy和strong最終都會(huì)返回一個(gè)引用計(jì)數(shù)為1的對(duì)象,所以單單從內(nèi)存管理上說copy和strong并無任何區(qū)別,但是copy始終會(huì)返回一個(gè)不可變對(duì)象,他的值是不會(huì)被修改的。

而strong不同,被strong修飾的對(duì)象,可能會(huì)被可變對(duì)象賦值,從而在外部導(dǎo)致不可預(yù)料的被更改的情況。

總而言之,是否使用copy或strong還是根據(jù)具體場(chǎng)景來定,這里還有個(gè)性能優(yōu)化的小技巧,如果copy的是可變的對(duì)象,會(huì)對(duì)它做一次完全深拷貝/不完全深拷貝,性能上是肯定不如strong直接引用計(jì)數(shù)+1來的快。

六、結(jié)尾

這次的修飾詞講解到此就告一段落了,然后想一下這周寫什么樣的文章。

好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • 解密ios響應(yīng)鏈的工作原理

    解密ios響應(yīng)鏈的工作原理

    本文將深入探討事件響應(yīng)鏈的工作原理,并提供?Swift?中的代碼示例來幫助讀者更好地理解這一概念
    2023-03-03
  • iOS自定義時(shí)間滾動(dòng)選擇控件

    iOS自定義時(shí)間滾動(dòng)選擇控件

    這篇文章主要為大家詳細(xì)介紹了iOS自定義時(shí)間滾動(dòng)選擇控件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • iOS判斷是否越獄設(shè)備方法示例

    iOS判斷是否越獄設(shè)備方法示例

    這篇文章主要給大家介紹了關(guān)于iOS判斷是否越獄設(shè)備的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)各位iOS開發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08
  • IOS 獲取已連接的wifi信息的實(shí)現(xiàn)代碼

    IOS 獲取已連接的wifi信息的實(shí)現(xiàn)代碼

    這篇文章主要介紹了IOS 獲取已連接的wifi信息的實(shí)現(xiàn)代碼的相關(guān)資料,這里提供實(shí)現(xiàn)代碼幫助大家學(xué)習(xí)理解這部分內(nèi)容,需要的朋友可以參考下
    2017-08-08
  • iOS開發(fā)Masonry與Frame布局差異示例詳解

    iOS開發(fā)Masonry與Frame布局差異示例詳解

    這篇文章主要為大家介紹了iOS開發(fā)Masonry與Frame布局差異示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • ios實(shí)現(xiàn)簡(jiǎn)單隨便移動(dòng)的AR功能

    ios實(shí)現(xiàn)簡(jiǎn)單隨便移動(dòng)的AR功能

    這篇文章主要為大家詳細(xì)介紹了ios實(shí)現(xiàn)簡(jiǎn)單隨便走的AR功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • 用iOS代碼獲取APP啟動(dòng)頁圖片

    用iOS代碼獲取APP啟動(dòng)頁圖片

    這篇文章主要為大家詳細(xì)介紹了用iOS代碼獲取APP啟動(dòng)頁圖片的相關(guān)資料,感興趣的小伙伴們可以參考一下
    2016-08-08
  • iOS 自定義返回按鈕保留系統(tǒng)滑動(dòng)返回功能

    iOS 自定義返回按鈕保留系統(tǒng)滑動(dòng)返回功能

    這篇文章主要介紹了iOS 自定義返回按鈕,保留系統(tǒng)滑動(dòng)返回功能,實(shí)現(xiàn)方法非常簡(jiǎn)單,具有參考借鑒價(jià)值,需要的朋友參考下吧
    2017-01-01
  • iOS中UIScrollView嵌套UITableView的實(shí)踐教程

    iOS中UIScrollView嵌套UITableView的實(shí)踐教程

    在UIScrollView嵌套UITableView的問題相信大家都遇到過,小編最近在工作中就遇到了這個(gè)問題,所以這篇文章主要介紹了iOS中UIScrollView嵌套UITableView的相關(guān)資料,文中介紹的方法是通過自己的實(shí)踐所得來的,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-05-05
  • iOS開發(fā)之UIPickerView實(shí)現(xiàn)城市選擇器的步驟詳解

    iOS開發(fā)之UIPickerView實(shí)現(xiàn)城市選擇器的步驟詳解

    這篇文章給大家介紹iOS利用控件UIPickerView實(shí)現(xiàn)城市選擇器的效果,選擇城市這一功能相信在大家日常開發(fā)的時(shí)候經(jīng)常遇見,下面就來看看詳細(xì)的實(shí)現(xiàn)過程,有需要的可以參考借鑒。
    2016-09-09

最新評(píng)論

赤壁市| 宁河县| 叙永县| 拜城县| 闽侯县| 黄冈市| 嘉荫县| 新沂市| 馆陶县| 松阳县| 胶南市| 休宁县| 无极县| 筠连县| 樟树市| 乳山市| 北京市| 措美县| 颍上县| 扎鲁特旗| 酉阳| 麻栗坡县| 宜章县| 冀州市| 陆丰市| 兴安盟| 苍溪县| 视频| 东安县| 南涧| 丹江口市| 库车县| 正镶白旗| 绵阳市| 宜川县| 乌兰察布市| 北宁市| 双鸭山市| 满洲里市| 绥江县| 米林县|