1. #import 跟#include 又什么區(qū)別,@class呢, #import<> 跟 #import””又什么區(qū)別?
答:#import是Objective-C導(dǎo)入頭文件的關(guān)鍵字,#include是C/C++導(dǎo)入頭文件的關(guān)鍵字,使用#import頭文件會(huì)自動(dòng)只導(dǎo)入一次,不會(huì)重復(fù)導(dǎo)入,相當(dāng)于#include和#pragma once;@class告訴編譯器某個(gè)類的聲明,當(dāng)執(zhí)行時(shí),才去查看類的實(shí)現(xiàn)文件,可以解決頭文件的相互包含;#import<>用來包含系統(tǒng)的頭文件,#import””用來包含用戶頭文件。
2. 原子(atomic)跟非原子(non-atomic)屬性有什么區(qū)別?
答:atomic提供多線程安全。是防止在寫未完成的時(shí)候被另外一個(gè)線程讀取,造成數(shù)據(jù)錯(cuò)誤
non-atomic:在自己管理內(nèi)存的環(huán)境中,解析的訪問器保留并自動(dòng)釋放返回的值,如果指定了 ? ? ?nonatomic ,那么訪問器只是簡(jiǎn)單地返回這個(gè)值。
3.instancetype與id的區(qū)別
區(qū)別1:
在ARC(Auto Reference Count)環(huán)境下:
instancetype用來在編譯期確定實(shí)例的類型,而使用id的話,編譯器不檢查類型, 運(yùn)行時(shí)檢查類型.
在MRC(Manual Reference Count)環(huán)境下:
instancetype和id一樣,不做具體類型檢查
區(qū)別2:
id可以作為方法的參數(shù),但instancetype不可以
instancetype只適用于初始化方法和便利構(gòu)造器的返回值類型
區(qū)別:
1>instancetype在類型表示上,跟id一樣,可以表示任何對(duì)象類型
2>instancetype只能用在返回值類型上,不能像id一樣用在參數(shù)類型上
3>instancetype比id多一個(gè)好處:編譯器會(huì)檢測(cè)instancetype的真實(shí)類型
4. weak 和 strong 區(qū)別
?weak相當(dāng)于老版本的assign,strong相當(dāng)于retain
(weak和strong)不同的是 當(dāng)一個(gè)對(duì)象不再有strong類型的指針指向它的時(shí)候 它會(huì)被釋放 ,即使還有weak型指針指向它。
一旦最后一個(gè)strong型指針離去 ,這個(gè)對(duì)象將被釋放,所有剩余的weak型指針都將被清除。
可能有個(gè)例子形容是妥當(dāng)?shù)摹?/p>
想象我們的對(duì)象是一條狗,狗想要跑掉(被釋放)。
strong型指針就像是栓住的狗。只要你用牽繩掛住狗,狗就不會(huì)跑掉。如果有5個(gè)人牽著一條狗(5個(gè)strong型指針指向1個(gè)對(duì)象),除非5個(gè)牽繩都脫落 ,否著狗是不會(huì)跑掉的。
weak型指針就像是一個(gè)小孩指著狗喊到:“看!一只狗在那” 只要狗一直被栓著,小孩就能看到狗,(weak指針)會(huì)一直指向它。只要狗的牽繩脫落,狗就會(huì)跑掉,不管有多少小孩在看著它。
只要最后一個(gè)strong型指針不再指向?qū)ο?,那么?duì)象就會(huì)被釋放,同時(shí)所有的weak型指針都將會(huì)被清除。

5.友盟報(bào)錯(cuò)可以查到具體某一行的錯(cuò)誤,原理是什么
錯(cuò)誤分析是友盟為移動(dòng)開發(fā)者提供的Crash收集和分析工具,幫助開發(fā)者監(jiān)測(cè)App在移動(dòng)設(shè)備上的運(yùn)行狀況,及時(shí)發(fā)現(xiàn)并解決錯(cuò)誤,提升App的穩(wěn)定性。
6. 深拷貝(內(nèi)容拷貝) 淺拷貝(指針拷貝) 偽拷貝
原則: 看是否產(chǎn)生新的對(duì)象
例如:如果本身是一個(gè)不可變字符串?
調(diào)用copy 方法 ?產(chǎn)生一個(gè)不可變字符串 ?此時(shí)和原來地址一樣, 既指向同一個(gè)內(nèi)存地址 ?沒有產(chǎn)生新對(duì)象
調(diào)用mutableCopy 方法? 產(chǎn)生一個(gè)可變字符串 ? 由不可變 -> 可變 ?此時(shí)產(chǎn)生新的對(duì)象 ?所以是深拷貝
若本身是一個(gè)可變字符串
調(diào)用copy 方法? 產(chǎn)生一個(gè)不可變字符串? 此時(shí)和原來地址不一樣, 既指向不同內(nèi)存地址 ?產(chǎn)生新對(duì)象 ?既深拷貝
調(diào)用mutableCopy 方法? 產(chǎn)生一個(gè)可變字符串 ? 此時(shí)產(chǎn)生新的對(duì)象? 所以是深拷貝
若此時(shí)是一個(gè)自定義的Person對(duì)象想實(shí)現(xiàn)拷貝, 內(nèi)部實(shí)現(xiàn)如下:
先遵守 NSCopying 協(xié)議 ? ?--> 必須實(shí)現(xiàn) copyWithZone: 的方法 ;
字符串為什么要用copy 而不用strong ?
若用strong: setter方法實(shí)現(xiàn)如下:
//- (void)setName:(NSString *)name? {? _name = name; }
此時(shí)改變其他對(duì)象會(huì)改變?cè)瓉淼膶傩?如這里的name, 也就是傳什么就是什么
若用copy : setter方法實(shí)現(xiàn)如下:
//- (void)setName:(NSString *)name {_name = [name copy]; }//只會(huì)調(diào)copy ?不會(huì)調(diào)mutableCopy ?注意
相當(dāng)于拷貝一份出來,不是同一個(gè)對(duì)象 不會(huì)影響原來的屬性值
所有, 當(dāng)你希望以后可以改變?cè)瓉淼木陀胹trong , 反之, 取決于使用者,沒有絕對(duì)的對(duì)錯(cuò)
面試: /** name屬性值永遠(yuǎn)是不可變,所以定義為NSMutableString是不合理的 */
@property (nonatomic, copy) NSMutableString *name;
此時(shí) setter是 {_name = [name copy]; } ?是不可變的 而 你屬性是可變, 別人會(huì)誤以為是可變,容易把當(dāng)可變用, 此時(shí)會(huì)崩潰, 所有此時(shí)不嚴(yán)謹(jǐn)
7. block 為什么要使用copy修飾
聲明block的時(shí)候都是用copy來修飾
使用copy修飾的原因:
block本身是像對(duì)象一樣可以retain,和release。但是,block在創(chuàng)建的時(shí)候,它的內(nèi)存是分配在棧(stack)上,而不是在堆(heap)上。他本身的作于域是屬于創(chuàng)建時(shí)候的作用域,一旦在創(chuàng)建時(shí)候的作用域外面調(diào)用block將導(dǎo)致程序崩潰。
使用retain也可以,但是block的retain行為默認(rèn)是用copy的行為實(shí)現(xiàn)的,因?yàn)閎lock變量默認(rèn)是聲明為棧變量的,為了能夠在block的聲明域外使用,所以要把block拷貝(copy)到堆,所以說為了block屬性聲明和實(shí)際的操作一致,最好聲明為copy。
堆和棧的區(qū)別:
一、堆??臻g分配區(qū)別:
1、棧(操作系統(tǒng)):由操作系統(tǒng)自動(dòng)分配釋放 ,存放函數(shù)的參數(shù)值,局部變量的值等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧;
2、堆(操作系統(tǒng)): 一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時(shí)可能由OS回收,分配方式倒是類似于鏈表。
二、堆棧緩存方式區(qū)別:
1、棧使用的是一級(jí)緩存, 他們通常都是被調(diào)用時(shí)處于存儲(chǔ)空間中,調(diào)用完畢立即釋放;
2、堆是存放在二級(jí)緩存中,生命周期由虛擬機(jī)的垃圾回收算法來決定(并不是一旦成為孤兒對(duì)象就能被回收)。所以調(diào)用這些對(duì)象的速度要相對(duì)來得低一些。
三、堆棧數(shù)據(jù)結(jié)構(gòu)區(qū)別:
堆(數(shù)據(jù)結(jié)構(gòu)):堆可以被看成是一棵樹,如:堆排序;
棧(數(shù)據(jù)結(jié)構(gòu)):一種先進(jìn)后出的數(shù)據(jù)結(jié)構(gòu)。
著作權(quán)歸作者所有,轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),并標(biāo)注“簡(jiǎn)書作者”。