1吟榴、UIView 和 CALayer 的區(qū)別
1. UIView可以響應事件捧颅,Layer不可以手报,因為UIView繼承自UIResponder類宽气,而 CALayer直接繼承 NSObject
2. UIView自身不能設置圓角等效果, 而CALayer可設置邊框, 圓角, 陰影和變換變形等
3. UIView主要是對顯示內(nèi)容的管理, 而CALayer主要是顯示內(nèi)容的繪制
4. CALayer默認修改屬性支持隱式動畫
2、RunLoop和多線程的關系
1. 每條線程都有唯一的一個 RunLoop 對象與之對應的
2. 主線程的 RunLoop 是自動創(chuàng)建并啟動曙博,UIApplicationMain()函數(shù)拥刻,這個方法會為main thread設置一個NSRunLoop對象。
這就解釋了:為什么我們的應用可以在無人操作的時候休息父泳,需要讓它干活的時候又能立馬響應般哼。
3. 子線程的 RunLoop 需要手動創(chuàng)建,run loop默認是沒有啟動的惠窄,如果你需要更多的線程交互則可以手動配置和啟動
4. 在任何一個 Cocoa 程序的線程中蒸眠,都可以通過以下代碼來獲取到當前線程的 run loop 。
NSRunLoop *runloop = [NSRunLoop currentRunLoop];
3杆融、__block 和 __weak 的區(qū)別
1. __weak 本身是可以避免循環(huán)引用的問題的楞卡,但是其會導致外部對象釋放了之后,block 內(nèi)部也訪問不到這個對象的問題脾歇,
我們可以通過在 block 內(nèi)部聲明一個 __strong 的變量來指向 weakObj蒋腮,使外部對象既能在 block 內(nèi)部保持住,又能避免循環(huán)引用的問題藕各。
2. __block 本身無法避免循環(huán)引用的問題池摧,但是我們可以通過在 block 內(nèi)部手動把 blockObj 賦值為 nil 的方式來避免循環(huán)引用的問題。
3. __block 修飾的變量在 block 內(nèi)外都是唯一的激况,要注意這個特性可能帶來的隱患作彤。
4. __block在ARC環(huán)境下,無法避免循環(huán)引用的問題乌逐。在非arc下竭讳,__block是可以避免引用循環(huán)的
4、Runtime 怎樣實現(xiàn) weak 屬性的
通過關聯(lián)屬性來實現(xiàn)
//聲明一個weak屬性浙踢,以delegate為例
@property (nonatomic, weak) id delegate;
//重寫getter绢慢、setter方法
- (id)delegate {
return objc_getAssociatedObject(self, @"__delegate__key");
}
//指定使用OBJC_ASSOCIATION_ASSIGN
- (void)setDelegate:(id)delegate {
objc_setAssociatedObject(self, @"__delegate__key", delegate, OBJC_ASSOCIATION_ASSIGN);
}
5、筆試題:
寫出打印結(jié)果洛波,并說明為什么
//全民快樂筆試題
- (void)gcdTest {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"4");
});
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"5");
});
[self performSelector:@selector(test2)];
[self performSelector:@selector(test3) withObject:nil afterDelay:0];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"6");
});
[self test1];
}
- (void)test1 {
NSLog(@"1");
}
- (void)test2 {
NSLog(@"2");
}
- (void)test3 {
NSLog(@"3");
}
(D沤妗!7芩辍思瘟!運行結(jié)果是:216453 )
# 解決思路
1. 搞清楚下面兩者區(qū)別
dispatch_async
dispatch_sync
2.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"4");
});
等價于
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"4");
});
3. [self performSelector:@selector(test2)];
等價于
[self test2];
4.
[self performSelector:@selector(test3) withObject:nil afterDelay:0];
等價于
dispatch_async(dispatch_get_main_queue(), ^{
[self test3];
});
5. 要知道在主線程上運行以下兩句話, 這里查文檔好好理解一下吧
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"A");
});
NSLog(@"B");
打印結(jié)果是 BA
6.
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"6");
});
這個數(shù)字出現(xiàn)比較隨機,所以不用太在意
所以上面代碼簡化為,(忽略6)
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"4");
});
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"5");
});
[self test2];
dispatch_async(dispatch_get_main_queue(), ^{
[self test3];
});
[self test1];
結(jié)果: 21453 (6出現(xiàn)的位置比較隨機)