一些iOS面試點(diǎn)和文章記錄

幾個(gè)概念點(diǎn)分析的比較好的文章

整理的部分iOS 面試題

什么時(shí)候在 block 中不需要使用 weakSelf?

問題:我們知道,在使用 block 的時(shí)候,為了避免產(chǎn)生循環(huán)引用,通常需要使用 weakSelf 與 strongSelf,寫下面這樣的代碼:

__weak typeof(self) weakSelf = self;
[self doSomeBlockJob:^{
    __strong typeof(weakSelf) strongSelf = weakSelf;
    if (strongSelf) {
        ...
    }
}];
那么請問:什么時(shí)候在 block里面用self,不需要使用weakself?

當(dāng)block本身不被self 持有,而被別的對象持有,同時(shí)不產(chǎn)生循環(huán)引用的時(shí)候,就不需要使用weakself了。最常見的代碼就是UIView的動(dòng)畫代碼,我們在使用UIView animateWithDuration:animations方法 做動(dòng)畫的時(shí)候,并不需要使用weakself,因?yàn)橐贸钟嘘P(guān)系是:

UIView 的某個(gè)負(fù)責(zé)動(dòng)畫的對象持有block,block 持有了self因?yàn)?self 并不持有 block,所以就沒有循環(huán)引用產(chǎn)生,因?yàn)榫筒恍枰褂?weak self 了。

[UIView animateWithDuration:0.2 animations:^{
    self.alpha = 1;
}];
當(dāng)動(dòng)畫結(jié)束時(shí),UIView會(huì)結(jié)束持有這個(gè) block,如果沒有別的對象持有block的話,block 對象就會(huì)釋放掉,從而 block會(huì)釋放掉對于 self 的持有。整個(gè)內(nèi)存引用關(guān)系被解除。

在使用 block 的時(shí)候,為了避免產(chǎn)生循環(huán)引用,通常需要使用 weakSelf 與 strongSelf,為什么 block 里面還需要寫一個(gè) strong self,如果不寫會(huì)怎么樣?

在 block 中先寫一個(gè) strong self,其實(shí)是為了避免在 block 的執(zhí)行過程中,突然出現(xiàn) self 被釋放的尷尬情況。通常情況下,如果不這么做的話,還是很容易出現(xiàn)一些奇怪的邏輯,甚至閃退。

我們以AFNetworking中的AFNetworkReachabilityManager.m的一段代碼舉例:

__weak __typeof(self)weakSelf = self;
AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) {
    __strong __typeof(weakSelf)strongSelf = weakSelf;
    strongSelf.networkReachabilityStatus = status;
    if (strongSelf.networkReachabilityStatusBlock) {strongSelf.networkReachabilityStatusBlock(status);
    }
};

如果沒有strongSelf的那行代碼,那么后面的每一行代碼執(zhí)行時(shí),self都可能被釋放掉了,這樣很可能造成邏輯異常。

特別是當(dāng)我們正在執(zhí)行 strongSelf.networkReachabilityStatusBlock(status); 這個(gè) block閉包時(shí),如果這個(gè) block 執(zhí)行到一半時(shí) self 釋放,那么多半情況下會(huì) Crash。

weak 的內(nèi)部實(shí)現(xiàn)原理

  • weak 變量在引用計(jì)數(shù)為0時(shí),會(huì)被自動(dòng)設(shè)置成 nil,這個(gè)特性是如何實(shí)現(xiàn)的?

《Objective-C高級編程》一書中也介紹了相關(guān)的內(nèi)容。
簡單來說,系統(tǒng)有一個(gè)全局的 CFMutableDictionary 實(shí)例,來保存每個(gè)對象的 weak 指針列表,因?yàn)槊總€(gè)對象可能有多個(gè) weak 指針,所以這個(gè)實(shí)例的值是 CFMutableSet 類型。

剩下我們要做的,就是在引用計(jì)數(shù)變成 0 的時(shí)候,去這個(gè)全局的字典里面,找到所有的 weak 指針,將其值設(shè)置成 nil。如何做到這一點(diǎn)呢?Friday QA 上介紹了一種類似 KVO 實(shí)現(xiàn)的方式。當(dāng)對象存在 weak 指針時(shí),我們可以將這個(gè)實(shí)例指向一個(gè)新創(chuàng)建的子類,然后修改這個(gè)子類的 release 方法,在 release 方法中,去從全局的 CFMutableDictionary 字典中找到所有的 weak 對象,并且設(shè)置成 nil。我摘抄了 Friday QA 上的實(shí)現(xiàn)的核心代碼,如下:

Class subclass = objc_allocateClassPair(class, newNameC, 0);
Method release = class_getInstanceMethod(class, @selector(release));
Method dealloc = class_getInstanceMethod(class, @selector(dealloc));
class_addMethod(subclass, @selector(release), (IMP)CustomSubclassRelease, method_getTypeEncoding(release));
class_addMethod(subclass, @selector(dealloc), (IMP)CustomSubclassDealloc, method_getTypeEncoding(dealloc));
objc_registerClassPair(subclass);

以下代碼運(yùn)行結(jié)果如何

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"1");
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"2");
    });
    NSLog(@"3");
}

只能輸出1,然后線程主線程死鎖
因?yàn)橹骶€程阻塞。
dispatch_async(dispatch_get_main_queue(), ^{
用async異步就不會(huì)掐死線程了
});

( 不管是同步函數(shù)或者是異步函數(shù),都會(huì)將block里面的內(nèi)容派遣到對應(yīng)的隊(duì)列的最下面。,我的理解是,如果是異步的情況下,輸出順序應(yīng)該是1-3-2,,在主線程隊(duì)列后插入了一個(gè)Block,在log“3”之后執(zhí)行。 所以在主線程同步的情況下變成了 要執(zhí)行l(wèi)og“2”, 先執(zhí)行l(wèi)og“3”, 但是log“2”的執(zhí)行是主線程同步,所以在log“2”執(zhí)行完之前,log“3”不會(huì)執(zhí)行,所以會(huì)造成死鎖)

這個(gè)寫法會(huì)出什么問題: @property (copy) NSMutableArray *array;

兩個(gè)問題:1、添加,刪除,修改數(shù)組內(nèi)的元素的時(shí)候,程序會(huì)因?yàn)檎也坏綄?yīng)的方法而崩潰.因?yàn)?copy 就是復(fù)制一個(gè)不可變 NSArray 的對象;2、使用了 atomic 屬性會(huì)嚴(yán)重影響性能 ;

第1條的相關(guān)原因在下文中有論述《用@property聲明的NSString(或NSArray,NSDictionary)經(jīng)常使用 copy 關(guān)鍵字,為什么?如果改用strong關(guān)鍵字,可能造成什么問題?》 以及上文《怎么用 copy 關(guān)鍵字?》也有論述。

比如下面的代碼就會(huì)發(fā)生崩潰

// .h文件
// http://weibo.com/luohanchenyilong/
// https://github.com/ChenYilong
// 下面的代碼就會(huì)發(fā)生崩潰

@property (nonatomic, copy) NSMutableArray *mutableArray;
// .m文件
// http://weibo.com/luohanchenyilong/
// https://github.com/ChenYilong
// 下面的代碼就會(huì)發(fā)生崩潰

NSMutableArray *array = [NSMutableArray arrayWithObjects:@1,@2,nil];
self.mutableArray = array;
[self.mutableArray removeObjectAtIndex:0];

接下來就會(huì)奔潰:

 -[__NSArrayI removeObjectAtIndex:]: unrecognized selector sent to instance 0x7fcd1bc30460

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 把網(wǎng)上的一些結(jié)合自己面試時(shí)遇到的面試題總結(jié)了一下,以后有新的還會(huì)再加進(jìn)來。 1. OC 的理解與特性 OC 作為一...
    AlaricMurray閱讀 2,668評論 0 20
  • 1. 單例寫法 單例模式確保某一個(gè)類只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例。 一般情況下, 如果一個(gè)...
    sellse閱讀 1,092評論 0 1
  • http://blog.csdn.net/david21984/article/details/57451917 ...
    紫色冰雨閱讀 663評論 0 0
  • 第二章 被發(fā)現(xiàn)了 這一天傍晚,王若智照例趴在窗前,用望遠(yuǎn)鏡監(jiān)視著在街上遛彎的禿老亮。 現(xiàn)在是初春季節(jié),天氣乍暖還寒...
    1019d835891a閱讀 263評論 0 0
  • Overview Bcg729 is a software G729A encoder and decoder l...
    Flannery閱讀 1,264評論 0 0

友情鏈接更多精彩內(nèi)容