UIButton繼承關系: UIControl -> UIView -> UIResponder -> NSObject
Model View Controller(模型 視圖 控制器):Control 負責初始化 Model,并將 Model 傳遞給 View 去解析展示
MVP分為 Model(模型)、View(視圖)、Presenter(表示器)三部分組成,Presenter層,其負責調控View與Model之間的間接交互
Model(數(shù)據層)、ViewController/View(展示層)、ViewModel(數(shù)據模型):
MVVM模式主要是減輕Controller層或者View層的壓力,實現(xiàn)更加清晰化代碼。通過對ViewModel層的封裝:封裝業(yè)務邏輯處理,封裝網絡處理、封裝數(shù)據緩存等
iOS代理模式: 包含【委托對象】、【代理對象】和【協(xié)議】
[協(xié)議]:用來指定代理需要做的事
[委托對象]:根據協(xié)議,指定代理去完成什么功能
[代理對象]:根據協(xié)議,完成委托方需要實現(xiàn)的功能
iOS單例模式:確保某一個類只有一個實例,不能通過其它類來初始化自己,在程序運行的過程中只有一份,節(jié)約內存
iOS觀察者模式:定義對象間一對多依賴關系,使得每當一個對象狀態(tài)發(fā)生改變時,其相關依賴對象皆得到通知并被自動更新 NSNotificationCenter和KVO
適配器模式 && 策略模式 && 裝飾模式 && 工廠模式
NSTimer受RunLoop模式的影響:
timerWithTimeInterval: 不會自動加入運行循環(huán),需要我們手動指定模式,并手動加入運行循環(huán)
scheduledTimerWithTimeInterval: 自動以NSDefaultRunLoopModel模式加入運行循環(huán)
CADisplayLink:在屏幕每次刷新時執(zhí)行一次,創(chuàng)建的displayLink添加到runloop中,否則定時器不會執(zhí)行
[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
解決NSTimer循環(huán)引用:
1.使用NSTimer提供的API,在block中執(zhí)行定時任務
2.通過消息轉發(fā)的方法的方式,聲明弱代理
3. #pragma mark - 第一種方法:合適的時機關閉定時器
- (void)didMoveToParentViewController:(UIViewController *)parent
{
if (!parent) {
[_timer invalidate];
_timer = nil;
}
}
4.使用NSProxy,此方法無需經過消息轉發(fā),效率更高
線程?;?使用端口(addPort:forMode:)?;钭泳€程
同步與異步的區(qū)別:是否等待隊列的任務執(zhí)行結束,以及是否具備開啟新線程的能力。
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"sync - %@", [NSThread currentThread]);
});
dispatch_sync 立即阻塞當前的主線程,然后把 Block 中的任務放到 main_queue 中, main_queue 中的任務會被取出來放到主線程中執(zhí)行,但主線程這個時候已經被阻塞了
Runloop的作用:保持程序的持續(xù)運行、隨時處理各種事件、節(jié)省cpu資源(沒事件休息釋放資源)、渲染屏幕UI
Mode:主要用來指定事件在運行時循環(huán)的優(yōu)先級
- (void)setAbcString:(NSString *)abcString {
if (_abcString != abcString) {
[_abcString release];
_abcString = [abcString retain];
}
}
A = A+B B = A-B A = A-B
NSOperation是一個抽象類,也就是說它并不能直接使用,而是應該使用它的子類 NSInvocationOperation && NSBlockOperation && 自定義繼承NSOperation的子類
NSOperation的使用常常是配合NSOperationQueue來進行的
NSOperationQueue操作隊列之中,一旦添加到隊列,操作就會自動異步執(zhí)行(注意是異步)
如果沒有添加到隊列,而是使用start方法,則會在當前線程執(zhí)行
提供了GCD不好實現(xiàn)的:1.最大并發(fā)數(shù),2.暫停和繼續(xù),3.取消所有任務,4.依賴關系
- (id)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView *hitView = [super hitTest:point withEvent:event];
if (hitView == self) {
return nil;
} else {
return hitView;
}
}
觸摸hitTest的調用順序:touch -> UIApplication -> UIWindow -> UIViewController.view -> subViews -> ....-> 合適的view
事件的傳遞順序:view -> superView ...-> UIViewController.view -> UIViewController -> UIWindow -> UIApplication -> 事件丟棄
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
}
KVO全稱KeyValueObserving,是蘋果提供的一套事件通知機制。允許對象監(jiān)聽另一個對象特定屬性的改變,并在改變時接收到事件。由于KVO的實現(xiàn)機制,所以對屬性才會發(fā)生作用,一般繼承自NSObject的對象都默認支持KVO。
dispatch_barrier_async:會等待前邊追加到并發(fā)隊列中的任務全部執(zhí)行完畢之后,再將指定的任務追加到該異步隊列中 針對全局隊列無效
dispatch_after:延時執(zhí)行方法
dispatch_once: 一次性代碼(只執(zhí)行一次)
dispatch_apply:快速迭代方法
dispatch_group:
dispatch_group_notify
dispatch_group_enter
dispatch_group_leave
dispatch_semaphore:
dispatch_semaphore_create:創(chuàng)建一個 Semaphore 并初始化信號的總量
dispatch_semaphore_signal:發(fā)送一個信號,讓信號總量加 1
dispatch_semaphore_wait:可以使總信號量減 1,信號總量小于 0 時就會一直等待(阻塞所在線程),否則就可以正常執(zhí)行。
UIView為CALayer提供內容,以及負責處理觸摸等事件,參與響應鏈
CALayer負責顯示內容contents
Off-Screen Rendering:離屏渲染,分為CPU離屏渲染和GPU離屏渲染兩種形式。GPU離屏渲染指的是GPU在當前屏幕緩沖區(qū)外新開辟一個緩沖區(qū)進行渲染操作,應當盡量避免的則是GPU離屏渲染
export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)
iOS中的內存大致可以分為代碼區(qū),常量區(qū),全局/靜態(tài)區(qū),堆區(qū),棧區(qū);
棧區(qū)是由編譯器自動分配并釋放的,棧區(qū)地址從高到低分配;
堆區(qū)使用alloc分配內存,堆區(qū)地址是從低到高分配;
https://www.cnblogs.com/dins/p/ios-nei-cun-fen-pei-yu-fen-qu.html
結構體一般采用內存對齊的方式分配,其大小為結構體最寬成員大小的整數(shù)倍
bool 1個字節(jié) char 1個字節(jié)
int 4個字節(jié) float 4個字節(jié)
double 8個字節(jié) long 8個字節(jié) class isa 8個字節(jié)
autoreleasePool什么時候創(chuàng)建的,里面的對象又是什么時候釋放的?
App啟動后,蘋果在主線程 RunLoop 里注冊了兩個 Observer,其回調都是 _wrapRunLoopWithAutoreleasePoolHandler()
第一個 Observer 監(jiān)視的事件是 Entry(即將進入Loop),其回調內會調用 _objc_autoreleasePoolPush() 創(chuàng)建自動釋放池
第二個 Observer 監(jiān)視了兩個事件: BeforeWaiting(準備進入休眠) 時調用_objc_autoreleasePoolPop() 和 _objc_autoreleasePoolPush() 釋放舊的池并創(chuàng)建新池;Exit(即將退出Loop) 時調用 _objc_autoreleasePoolPop() 來釋放自動釋放池
手動autoreleasePool:@autoreleasepool {}方式手動創(chuàng)建autoreleasepool對象,出了autoreleasepool的大括號就釋放了
/**直接進行消息發(fā)送機制: objc_msgSend **/
- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
/**使用Runloop方法 **/
- (void)performSelector:(SEL)aSelector withObject:(nullable id)anArgument afterDelay:(NSTimeInterval)delay inModes:(NSArray<NSRunLoopMode> *)modes;
- (void)performSelector:(SEL)aSelector withObject:(nullable id)anArgument afterDelay:(NSTimeInterval)delay;
waitUntilDone : YES, 需要等待這個selector 執(zhí)行完之后,才會往下執(zhí)行,相當于同步
waitUntilDone : NO, 不用等待這個selector,就會往下執(zhí)行,相當于異步
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thread waitUntilDone:(BOOL)wait;
如果,當前線程就是主線程,那么aSelector方法會馬上執(zhí)行。
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
+ (void)load {} runtime加載類和分類的時候調用 直接拿到函數(shù)地址,直接調用
1.先調用父類的load
2.再調用子類的load
3.再調用分類的load,先編譯先調用
+ (void)initialize{} 當前類第一次接收到消息的時候調用 通過消息發(fā)送方式
1.先調用父類的initialize
2.再調用子類的initialize
3.子類未實現(xiàn)initialize方法時,會調用父類initialize方法
// 串行隊列的創(chuàng)建方法
dispatch_queue_t queue = dispatch_queue_create("net.bujige.testQueue", DISPATCH_QUEUE_SERIAL);
// 并發(fā)隊列的創(chuàng)建方法
dispatch_queue_t queue = dispatch_queue_create("net.bujige.testQueue", DISPATCH_QUEUE_CONCURRENT);
// 全局隊列
dispatch_get_main_queue()
// 全局并發(fā)隊列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
同步執(zhí)行任務:
dispatch_sync(queue, ^{
// 這里放同步執(zhí)行任務代碼
});
異步執(zhí)行任務:
dispatch_async(queue, ^{
// 這里放異步執(zhí)行任務代碼
});
柵欄函數(shù):
放全局并發(fā)隊列跟異步是同一個效果 A、B操作、柵欄柵欄柵欄操作、C、D操作并發(fā)執(zhí)行
放自己創(chuàng)建的并發(fā)隊列則有效 A、B操作并發(fā)執(zhí)行 柵欄柵欄柵欄操作 C、D操作并發(fā)執(zhí)行
dispatch_queue_t queue = dispatch_queue_create("testqueue",DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue,^{
for (int i = 0; i < 3; i++) {
CHSLOG(@"A操作");
}
});
dispatch_async(queue,^{
for (int i = 0; i < 3; i++) {
CHSLOG(@"B操作");
}
});
dispatch_barrier_async(queue,^{
for (int i = 0; i < 3; i++) {
CHSLOG(@"柵欄柵欄柵欄操作");
}
});
dispatch_async(queue,^{
for (int i = 0; i < 3; i++) {
CHSLOG(@"C操作");
}
});
dispatch_async(queue,^{
for (int i = 0; i < 3; i++) {
CHSLOG(@"D操作");
}
});
類擴展和分類的區(qū)別:
類擴展:編譯的時候會把屬性和方法一起放到類中
分類:利用Runtime把屬性和方法放到原類中,同名方法會覆蓋掉原來類中的方法,優(yōu)先調用后編譯的方法
struct __main_block_impl_0 {
struct __block_impl impl;
struct __main_block_desc_0* Desc;
int a;
__Block_byref_b_0 *b;
__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int _a, int flags=0) : a(_a) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
}
struct __Block_byref_b_0 {
void *__isa;
__Block_byref_b_0 *__forwarding;
int __flags;
int __size;
int b;
};
struct __block_impl {
void *isa;
int Flags;
int Reserved;
void *FuncPtr;
}
block = &__main_block_impl_0(__main_block_func_0, &__main_block_desc_0_DATA, a)
block->FuncPtr(block);
獲取到的基礎變量的值在block初始化的時候已經確定了,block外部的變量a在后續(xù)無論做什么操作,都不會影響block內部保存的變量a
UIView 繼承 UIResponder,而 UIResponder 是響應者對象,可以對iOS 中的事件響應及傳遞,CALayer 沒有繼承自 UIResponder,所以 CALayer 不具備響應處理事件的能力
self和super底層實現(xiàn)原理:
id objc_msgSend(id theReceiver, SEL theSelector, ...) 當使用 self 調用方法時,會從當前類的方法列表中開始找,如果沒有,就從父類中再找;
id objc_msgSendSuper(struct objc_super *super, SEL op, ...) 而當使用 super 時,則從父類的方法列表中開始找,然后調用父類的這個方法
@synthesize 是如果你沒有手動實現(xiàn) setter 方法和 getter 方法,那么編譯器會自動為你加上這兩個方法
@dynamic 告訴編譯器:屬性的 setter 與 getter 方法由用戶自己實現(xiàn),不自動生成
oc調用js代碼兩種方式:
1.通過webVIew調用 webView stringByEvaluatingJavaScriptFromString: 調用
2.通過JSContext調用[context evaluateScript:];
物理層 數(shù)據鏈路層 網絡層 傳輸層(TCP協(xié)議) 會話層 表示層 應用層(HTTP協(xié)議)
TCP:面向連接、傳輸可靠(保證數(shù)據正確性,保證數(shù)據順序)、用于傳輸大量數(shù)據(流模式)、速度慢,建立連接需要開銷較多(時間,系統(tǒng)資源)。
UDP:面向非連接、傳輸不可靠、用于傳輸少量數(shù)據(數(shù)據包模式)、速度快。
- (void)viewDidLoad{
[super viewDidLoad];
dispatch_sync(dispatch_get_main_queue(),^{
NSLog(@"deadlock");
});
}
在主線程中運用主隊列同步,也就是把任務放到了主線程的隊列中。
同步對于任務是立刻執(zhí)行的,那么當把任務放進主隊列時,它就會立馬執(zhí)行,只有執(zhí)行完這個任務,viewDidLoad才會繼續(xù)向下執(zhí)行。
而 viewDidLoad 和任務都是在主隊列上的,由于隊列的先進先出原則,
任務又需等待viewDidLoad執(zhí)行完畢后才能繼續(xù)執(zhí)行,
viewDidLoad 和這個任務就形成了相互循環(huán)等待,就造成了死鎖。
dispatch_queue_t serialQueue = dispatch_queue_create("test",DISPATCH_QUEUE_SERIAL);
dispatch_async(serialQueue,^{
dispatch_sync(serialQueue,^{
NSLog(@"deadlock");
});
});
外面的函數(shù)無論是同步還是異步都會造成死鎖。
這是因為里面的任務和外面的任務都在同一個 serialQueue 隊列內,又是同步,這就和上邊主隊列同步的例子一樣造成了死鎖;
解決方法也和上邊一樣,將里面的同步改成異步dispatch_async
或者將 serialQueue 換成其他串行或并行隊列,都可以解決
dispatch_queue_t serialQueue = dispatch_queue_create("test",DISPATCH_QUEUE_SERIAL);
dispatch_queue_t serialQueue2 = dispatch_queue_create("test2",DISPATCH_QUEUE_SERIAL);
dispatch_async(serialQueue,^{
dispatch_sync(serialQueue2,^{
NSLog(@"deadlock");
});
});
這樣是不會死鎖的,并且 serialQueue和serialQueue2是在同一個線程中的。
5、自旋鎖:OSSpinLock
6、互斥鎖:pthread_mutex、@synchronized、NSLock、NSConditionLock 、NSCondition、NSRecursiveLock、dispatch_semaphore_t os_unfair_lock
對稱加密(3DES|AES|DES) 加密和解密使用同一個密鑰
非對稱加密(RSA) 需要兩個密鑰:公開密鑰(publickey) 和私有密(privatekey)
如果用公開密鑰對數(shù)據進行加密,只有用對應的私有密鑰才能解密。
如果用私有密鑰對數(shù)據進行加密,只有用對應的公開密鑰才能解密。
原始報文/摘要/數(shù)字簽名:原始報文即為經過加密處理的報文,當原始報文經過了一些hash算法處理之后就成為了數(shù)字摘要,再經過RSA處理之后,當數(shù)字摘要經過密鑰加密之后就成為了數(shù)字簽名
數(shù)字簽名的作用主要是:確保發(fā)送的報文沒有被篡改
class方法和object_getClass方法的區(qū)別:
object_getClass(obj): 返回的是obj的isa指針
[obj class]: obj為實例對象 返回的obj對象中的isa指針;
obj為類對象(包括元類和根類以及根元類) 返回的結果為調用者本身;
Class Extension在編譯的時候,它的數(shù)據就已經包含在類信息中;
Category是在運行時,才會將數(shù)據合并到類信息中; 為一個類添加額外的原來沒有變量,方法和屬性
iOS和h5之間的交互:
1.利用UIWebView交互 通過調用JS來實現(xiàn)OC調用JS stringByEvaluatingJavaScriptFromString
通過協(xié)議攔截實現(xiàn)JS調用OC webView:shouldStartLoadWithRequest:navigationType:
2.JavaScriptCore.framework原生框架
OC調用JS evalueScript()
3.WKWebView的交互 JS調用OC [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"Share"];
OC調用JS evaluateJavaScript:
4.WebViewJavascriptBridge
1、客戶端APP將蘋果APNS服務器返回的devicetoken發(fā)送給我們自己的服務端程序;
2、推消息時,我們服務器根據devicetoken向蘋果APNS服務器發(fā)送消息;
3、蘋果APNS服務器將消息根據devicetoken發(fā)送給客戶端;
iOS匯編相關知識:
1.寄存器: ARM64 有34個寄存器,包括31個通用寄存器、SP、PC、CPSR
2.通用寄存器:x0~x28(64位的) (w0~w28(32位)對應的的x0~x28的低32位) ,x0~x7一般是用來存儲函數(shù)的參數(shù),更多參數(shù),則用堆棧來傳遞,x0一般用作函數(shù)的返回值
3.PC: 程序計數(shù)器,存儲著當前執(zhí)行的指令
4.FP:棧頂指針,指向一個棧幀的頂部,當函數(shù)發(fā)生跳轉時,會記錄當時的棧的起始位置。
5.SP:棧指針(也稱為棧底指針),指向棧當前的位置。
6.CPSR:狀態(tài)寄存器
NZCV是狀態(tài)寄存器的條件標志位,分別代表運算過程中產生的狀態(tài),其中:
N, negative condition flag,一般代表運算結果是負數(shù)
Z, zero condition flag, 指令結果為0時Z=1,否則Z=0;
C, carry condition flag, 無符號運算有溢出時,C=1。
V, oVerflow condition flag 有符號運算有溢出時,V=1。
7.LR:通常稱X30為程序鏈接寄存器,保存子程序結束后需要執(zhí)行的下一條指令
8.wzr:32位零寄存器
9.xzr:64位零寄存器
mov X1,X0 將寄存器X0的值傳送到寄存器X1
add X0,X1,X2 寄存器X1和X2的值相加后傳送到X0
sub X0,X1,X2 寄存器X1和X2的值相減后傳送到X0
and X0,X0,#0xF X0的值與0xF相位與后的值傳送到X0
orr X0,X0,#9 X0的值與9相位或后的值傳送到X0
eor X0,X0,#0xF X0的值與0xF相異或后的值傳送到X0
ldr X5,[X6,#0x08] ld:load X6寄存器加0x08的和的地址值內的數(shù)據傳送到X5
ldp x29, x30, [sp, #0x10] ldp :load pair 一對寄存器, 從內存讀取數(shù)據到寄存器
str X0, [sp, #0x8] st:store, str:往內存中寫數(shù)據(偏移值為正); X0寄存器的數(shù)據傳送到SP+0x8地址值指向的存儲空間
stur w0, [x29, #-0x8] 往內存中寫數(shù)據(偏移值為負)
stp x29, x30, [sp, #0x10] store pair,存放一對數(shù)據, 入棧指令
cmp 比較指令,影響程序狀態(tài)寄存器CPSR
b 跳轉指令,可帶條件跳轉與cmp配合使用
bl 帶返回的跳轉指令, 返回地址保存到LR(X30)
ret:函數(shù)返回,相當于return
葉子函數(shù):
void test(){
int a = 2;
int b = 3;
}
sub sp, sp, #16 ; =16,sp棧頂指針上移16個字節(jié)
.cfi_def_cfa_offset 16
mov w8, #2 ;將2存入w8寄存器
str w8, [sp, #12] ;將w8寄存器的數(shù)據存入到sp下移12個字節(jié)的所在位置下面的4字節(jié)
mov w8, #3 ;將3存入w8寄存器
str w8, [sp, #8] ;將w8寄存器的數(shù)據存入到sp下移8個字節(jié)的所在位置下面的4字節(jié)
add sp, sp, #16 ; =16,sp棧頂指針下移16個字節(jié),恢復到初始位置
ret
非葉子函數(shù),除了葉子函數(shù),其他函數(shù)叫非葉子函數(shù):
void excute(){
int a = 4;
int b = 5;
test();
}
void test(){
int a = 2;
int b = 3;
}
Mach-O包括以下幾種類型:
OBJECT,指的是.o或.a文件(目標文件)
EXECUTE,指的是IPA拆包后的文件(可執(zhí)行文件)
DYLIB,指的是.dylib或.framework文件(動態(tài)庫文件)
DYLINKER,指的是動態(tài)連接器(動態(tài)鏈接器文件)
DSYM(符號表),指的是有保存符號信息用于分析閃退信息的文件(符號表文件)
加載過程:
1.把可執(zhí)行文件加載到內存中,并從它中分析出dyld的路徑,再把dyld加載到內存中,最后dyld遞歸加載所有的動態(tài)鏈接庫dylib
dyld可以用來加載以下三種類型的Mach-O文件
MH_EXECUTE
MH_DYLIB
MH_BUNDLE
.p12 文件:Mac本地生成的鑰匙對私鑰。由于私鑰是本地私有的,.p12將私鑰導出給其他團隊成員使用
當一個對象obj被weak指針指向時,這個weak指針會以obj作為key,weak指針的地址數(shù)組作為value,被存儲到sideTable類的weak_table這個散列表上對應的一個weak指針數(shù)組里面。
當一個對象obj的dealloc方法被調用時,Runtime會以obj為key,從sideTable的weak_table散列表中,找出對應的weak指針列表,然后將里面的weak指針逐個置為nil。
+ (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = self->ISA(); tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
- (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
+ (BOOL)isMemberOfClass:(Class)cls {
return self->ISA() == cls;
}
- (BOOL)isMemberOfClass:(Class)cls {
return [self class] == cls;
}
(lldb) e id $hgView = (id)0x7fdfc66127f0
(lldb) e (void)[$hgView setBackgroundColor:[UIColor redColor]]
(lldb) e (void)[CATransaction flush]
iOS UITableView 的 優(yōu)化:
1.Tableview 懶加載、Cell 重用
2.高度緩存(因為 heightForRowAtIndexPath: 是調用最頻繁的方法)
3.數(shù)據處理:
3.1.使用正確的數(shù)據結構來存儲數(shù)據
3.2.數(shù)據盡量采用局部的 section,或 cellRow 的刷新,避免 reloadData
3.3.大量數(shù)據操作時,使用異步子線程處理,避免主線程中直接操作
4.異步加載圖片:SDWebImage 的使用:
4.1.使用異步子線程處理,然后再返回主線程操作
4.2.圖片緩存處理,避免多次處理操作
5.按需加載內容,只顯示目標范圍內的 Cell 內容
6.減少Subviews 的數(shù)量
7.不要動態(tài)添加視圖或移除視圖,用hidden顯示(隱藏)Subviews
同步執(zhí)行(sync):
1.同步添加任務到指定的隊列中,在添加的任務執(zhí)行結束之前,會一直等待,直到隊列里面的任務完成之后再繼續(xù)執(zhí)行
2.只能在當前線程中執(zhí)行任務,不具備開啟新線程的能力
異步執(zhí)行(async)
1.異步添加任務到指定的隊列中,它不會做任何等待,可以繼續(xù)執(zhí)行任務
2.可以在新的線程中執(zhí)行任務,具備開啟新線程的能力
iOS編譯的過程:
預處理:處理以#開頭的命令,刪除注釋,解開宏定義等
編譯:詞法分析、語法分析、語義分析、中間代碼生成與優(yōu)化,最終生成匯編代碼
匯編:將匯編代碼翻譯成機器碼,生成.o目標文件
鏈接:將多個.o目標文件和其他函數(shù)庫鏈接成可執(zhí)行文件
記錄:
最后編輯于 :
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
相關閱讀更多精彩內容
- A記錄 A (Address) 記錄是用來指定域名對應的IP地址記錄,同時也可以設置域名的子域名,A記錄目標地址只...
- 成長記錄-連載(三十六) ——我的第一篇五千字長文,說了什么,你一定想不到 并不是不想每天寫公眾號,而是之前思考怎...
- 1. A記錄(IP解析) IP解析又叫A記錄,A (Address) 記錄是用來指域名對應的IP地址記錄。用戶可以...
- 好幾天沒有發(fā)文了,忙于學習,忙于期末考試,也有其他的一些原因。 今天是一個特別的日子,忙里偷閑,寫一篇。 記憶里多...
- #每日記錄#讓平凡的日子不再平凡 引起孩子探索的欲望,教給孩子探索的能力,并幫助他付諸行動,這是父母需要做的吧? ...