1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關(guān)咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務(wù)時間:8:30-17:00
      你可能遇到了下面的問題
      關(guān)閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
      iOS中有哪些常見的修飾詞-創(chuàng)新互聯(lián)

      iOS中有哪些常見的修飾詞,針對這個問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

      創(chuàng)新互聯(lián)建站堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的沐川網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

      一、readOnly,readWrite

      readOnly:

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

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

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

      回到正題,那么這意味著我們就完全沒辦法去修改readOnly的屬性了嗎?不然,如果你嘗試一下setValue:forKey:,你就會發(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 === 改變了

      而如果這個時候在MyFirstClass里加入

      @implementation MyFirstClass
      
      - (instancetype) init{
       self = [super init];
       if (self) {
       _string = @"來改變我啊";
       }
       
       return self;
      }
      
      + (BOOL) accessInstanceVariablesDirectly{
       return NO;
      }
      
      @end

      在運(yùn)行,boom,系統(tǒng)會報以下錯誤

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

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

      iOS中有哪些常見的修飾詞

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

      總結(jié):

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

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

      readWrite:

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

      二、nonatomic、atomic

      我們先看一下官方文檔

      iOS中有哪些常見的修飾詞

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

      atomic:

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

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

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

      nonatomic:

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

      三、assign、weak與strong

      assign:

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

      因?yàn)閍ssign并不會使對象的引用計數(shù)加1,也就是說如果用assign去修飾一個對象,這個對象會立即被釋放,重要的是assgin在被釋放的時候是不會自動置為nil,還是保留對象的指針地址,會形成野指針,這個時候向其發(fā)送消息就會崩潰,簡單實(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)行到最后一步的時候程序會崩潰報EXC_BAD_ACCESS的錯誤,如果打斷點(diǎn)的話會發(fā)現(xiàn)在執(zhí)行到這步的時候array還是有地址的。

      weak:

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

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

      strong:

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

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

      self.secondClass.array = [NSMutableArray array];

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

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

      copy與retain:

      • copy其實(shí)是建立了一個相同的對象,而retain不是.

      • copy是內(nèi)容拷貝,retain是指針拷貝.

      • copy是內(nèi)容的拷貝 ,對于像NSString,的確是這樣,如果拷貝的是NSArray這時只是copy了指向array中相對應(yīng)元素的指針.這便是所謂的"淺復(fù)制".

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

      四、copy與mutableCopy

      iOS中有哪些常見的修飾詞

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

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

      深拷貝:

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

      淺拷貝:

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

      接下來我們分兩個方面做測試:

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

      對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

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

      對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

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

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

      結(jié)論:

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

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

      ObjectHandleResult
      immutableObjectcopy指針拷貝
      immutableObjectmutableCopy深拷貝
      mutableObjectcopy深拷貝
      mutableObjectmutableCopy深拷貝

      2.對集合類對象的copy操作

      對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則不同。

      對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"];的時候兩個復(fù)制出來的數(shù)組的對象并沒有變化?

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

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

      結(jié)論:

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

      對mutableObject做copy或mutableCopy都是不完全深拷貝。

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

      ObjectHandleResult
      immutableObjectcopy指針拷貝
      immutableObjectmutableCopy不完全深拷貝
      mutableObjectcopy不完全深拷貝
      mutableObjectmutableCopy不完全深拷貝

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

      五、是用copy還是strong?

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

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

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

      關(guān)于iOS中有哪些常見的修飾詞問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司行業(yè)資訊頻道了解更多相關(guān)知識。

      另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)建站www.cdcxhl.com,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。


      當(dāng)前名稱:iOS中有哪些常見的修飾詞-創(chuàng)新互聯(lián)
      分享URL:http://www.ef60e0e.cn/article/ddjegi.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        郯城县| 乐至县| 长丰县| 道真| 定结县| 定结县| 岳池县| 台南县| 定兴县| 大悟县| 鹤峰县| 平远县| 抚远县| 蓬溪县| 黑山县| 盐源县| 浦县| 大理市| 晋州市| 乐至县| 芜湖县| 晋城| 民县| 亳州市| 沂南县| 攀枝花市| 云阳县| 大余县| 罗山县| 仪征市| 吉木乃县| 永修县| 尚志市| 湖口县| 吉安市| 济宁市| 泰顺县| 清水河县| 白朗县| 松阳县| 丰都县|