進(jìn)程
線程
一個(gè)線程同一時(shí)間只能做一件事(串行)
一個(gè)進(jìn)程可以同時(shí)做多個(gè)事情(并行)
多線程原理:
CPU同時(shí)只能處理一條線程,
CPU在多條線程間快速調(diào)度既荚,
調(diào)度時(shí)間足夠快,造成了在并發(fā)執(zhí)行的假象搀绣。
隱式創(chuàng)建子線程:
[self performSelectorInBackground : withObject: ];
主線程:
[self performSelectorOnMainThread: withObject: waitUntilDone:];
鎖? @synchronized(obj){ }? obj:唯一? 資源搶奪時(shí)使用
atomic:原子屬性? 為setter方法自動(dòng)加鎖? 線程安全
noatomic:適合內(nèi)存小的移動(dòng)設(shè)備? 一般用這個(gè)
線程間的通信
[self performSelectorOnMainThread: withObject: waitUntilDone:? modes:];
隊(duì)列 (FIFO先進(jìn)先出)
dispatch_sync? 在當(dāng)前線程執(zhí)行? 同步
dispatch_async? 在新的線程執(zhí)行 具備新建線程的能力? 異步
并發(fā): 允許多個(gè)任務(wù)同時(shí)執(zhí)行? 與異步函數(shù)搭配使用(隊(duì)列) dispatch_queue_concurrent
串行 :一個(gè)任務(wù)結(jié)束再執(zhí)行下一個(gè)任務(wù)? (隊(duì)列) dispatch_queue_serial
同步:異步: 是否具備開(kāi)啟新線程的能力
global_queue? 默認(rèn)全局并發(fā)隊(duì)列
main_queue? 主隊(duì)列? 在主線程執(zhí)行(無(wú)論同步異步)
各種組合? 除主隊(duì)列下飞袋,異步執(zhí)行的都會(huì)開(kāi)啟新的線程
? ? ? ? ? ? ? ? ? 特殊:主隊(duì)列中,同步執(zhí)行會(huì)卡死(如果同時(shí)在主線程執(zhí)行链患,互相等死)
使用sync函數(shù)往當(dāng)前串行隊(duì)列中添加任務(wù)巧鸭,會(huì)卡住當(dāng)前串行隊(duì)列
一次性代碼:
dispatch_once (全局的? 整個(gè)程序中只執(zhí)行一次)
快速迭代:
dispatch_apply? (放入并發(fā)隊(duì)列? 幾乎同時(shí)遍歷)?
隊(duì)列組:
dispatch_group_async
dispatch_group_notify? (group中的任務(wù)都結(jié)束再進(jìn)入notify)
合成圖片:
開(kāi)啟圖形上下文,UIGraphicsBeginImageContext(CGSizeMake())
然后? [image drawInRect:]
獲取合成圖片? UIGraphicsGetImgaeFromCurrentImageContext()
結(jié)束上下文? UIGraphicsEndImageContext
可以不用block形式:
dispatch_async_f? (函數(shù)形式) 可以傳值為一個(gè)函數(shù)
單例模式封裝宏:
使用GCD線程安全?
如果使用 ==nil方式? 使用@synchronized(obj){ }(大括號(hào)里是==nil的部分)
也可:XMGSingletonH(name)? + (instancetype)shareed##name? (保持方法名不雷同)
NSBlockOperation 在主線程執(zhí)行
NSBlockOperation? addExecutionBlock? 在子線程執(zhí)行
[NSOperationQueue mainQueue]? 主隊(duì)列?
[[NSOperationQueue alloc]init]? 其他隊(duì)列
自定義Operation 需要完成的任務(wù)寫(xiě)入.m的方法 -(void)main{}
suspended 掛起
canceled? 取消
這兩個(gè)操作會(huì)在當(dāng)前已經(jīng)開(kāi)始線程的任務(wù)結(jié)束后再掛起或者取消后面的線程任務(wù)
自定義operation內(nèi)在main方法內(nèi)麻捻,在耗時(shí)方法之間添加判斷 if(self.isCancled) return; 可以即時(shí)取消纲仍,否則不能停止。
[op3 addDependency:op1]; 依賴? op3 依賴op1? 1先3后 (在添加到隊(duì)列之前設(shè)置依賴)
還可跨隊(duì)列依賴
op.completeBlock = ^{} 監(jiān)聽(tīng)
什么時(shí)候用nsoperation 實(shí)現(xiàn)? 用gcd實(shí)現(xiàn)不了的情況
區(qū)別:operation可管理并發(fā)數(shù)贸毕,設(shè)置優(yōu)先級(jí)郑叠,設(shè)置依賴,設(shè)置暫停明棍,取消乡革;有kvo可監(jiān)聽(tīng)狀態(tài)是否執(zhí)行,取消摊腋,結(jié)束沸版;
通知在子線程可以觸發(fā)嗎
通知和線程的關(guān)系(可添加通知隊(duì)列)
1.在哪個(gè)線程發(fā)起通知,就在哪個(gè)線程接收通知?
2.默認(rèn)發(fā)送接收是同步的歌豺,即通知發(fā)送后推穷,在通知接收方法完成前,通知發(fā)送方法之后的代碼會(huì)等待執(zhí)行类咧,(若想不優(yōu)先通知接收方法馒铃,可以用以下方法通過(guò)設(shè)置postStyle)
[[NSNotificationQueue defaultQueue] enqueueNotification:notification postingStyle:NSPostWhenIdle];
方式一:
-(void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSNotificationName)aName object:(nullable id)anObject;
方式二:
-(id<NSObject>)addObserverForName:(nullable NSNotificationName)name object:(nullable id)obj queue:(nullable NSOperationQueue*)queue usingBlock:(void(^)(NSNotification*note))blockNS_AVAILABLE(10_6,4_0);
通知和runloop的關(guān)系
postingStyle:傳值不同則runloop處理時(shí)機(jī)不同
NSPostWhenIdle:runloop空閑時(shí)處理通知回調(diào)方法
NSPostASAP:runloop能處理時(shí)就處理
NSPostNow:runloop立刻處理
圖片緩存 存入library? cache? (注意:NSCacheDirectory? 不可document)
Documents:只有用戶生成的文件、其他數(shù)據(jù)及其他程序不能重新創(chuàng)建的文件痕惋,應(yīng)該保存在<Application_Home>/Documents 目錄下面区宇,并將通過(guò)iCloud自動(dòng)備份。
Library:存儲(chǔ)程序的默認(rèn)設(shè)置或其它狀態(tài)信息值戳,這個(gè)目錄下有兩個(gè)子目錄:Caches 和 Preferences议谷。
Caches:此目錄下文件不會(huì)在應(yīng)用退出刪除,可以重新下載或者重新生成的數(shù)據(jù)應(yīng)該保存在 /Library/Caches 目錄下面堕虹。舉個(gè)例子卧晓,比如雜志、新聞赴捞、地圖應(yīng)用使用的數(shù)據(jù)庫(kù)緩存文件和可下載內(nèi)容應(yīng)該保存到這個(gè)文件夾逼裆。
Preferences:目錄包含應(yīng)用程序的偏好設(shè)置文件。您不應(yīng)該直接創(chuàng)建偏好設(shè)置文件赦政,而是應(yīng)該使用NSUserDefaults類來(lái)取得和設(shè)置應(yīng)用程序的偏好胜宇。
tmp:只是臨時(shí)使用的數(shù)據(jù)應(yīng)該保存到 /tmp 文件夾。盡管 iCloud 不會(huì)備份這些文件,但在應(yīng)用在使用完這些數(shù)據(jù)之后要注意隨時(shí)刪除桐愉,避免占用用戶設(shè)備的空間财破。iPhone在重啟時(shí),會(huì)丟棄所有的tmp文件从诲。
RunLoop (主線程)
運(yùn)行循環(huán) (持續(xù)運(yùn)行? 處理事件? 節(jié)省CPU資源(沒(méi)事則休息))
UIApplicationMain 函數(shù)一直沒(méi)有返回? 保持程序持續(xù)運(yùn)行
每個(gè)線程都有一個(gè)RunLoop
子線程RunLoop不用創(chuàng)建? 而是調(diào)用 [NSRunLoop currentRunLoop];獲取
RunLoop{ mode [sourceobservertimer ]}
mode:默認(rèn)5個(gè) kCFRunLoopDefaultMode主線程? UITrackingRunLoopMode界面觸摸滑動(dòng)? NSRunLoopCommonMode通用占位并不是一種mode? 等
1.timer:CFRunLoopTimerRef 相當(dāng)于定時(shí)器NSTimer
[[NSRunLoop CurrentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]//只在主線程下運(yùn)行timer? 但是拖動(dòng)的時(shí)候不運(yùn)行? 使用NSRunLoopCommenModes 可以? 其包括default和 tracking
[NStimer scheduledTimerWithTimeInterval:];會(huì)自動(dòng)添加進(jìn)當(dāng)前runloop NSDefaultRunLoopMode
2.source:輸入源
函數(shù)調(diào)用棧分:source0(非基于Port) source1(基于Port左痢,接收分發(fā)系統(tǒng)事件)
3.observer:觀察者
監(jiān)聽(tīng)RunLoop狀態(tài)? CFRunLoopAddObserver
整體過(guò)程:
數(shù)據(jù)持久化
FMDB的事務(wù):大量數(shù)據(jù)同時(shí)插入時(shí)使用。
insert into語(yǔ)句很耗時(shí)盏求,普通時(shí)抖锥,以文件的形式存在磁盤(pán)亿眠,每次訪問(wèn)會(huì)打開(kāi)文件夾碎罚,大量數(shù)據(jù)時(shí)會(huì)很慢;以事務(wù)形式提交纳像,開(kāi)始事務(wù)后荆烈,進(jìn)行大量的操作語(yǔ)句都保存在內(nèi)存中,當(dāng)提交時(shí)才全部寫(xiě)入數(shù)據(jù)庫(kù)竟趾,只打開(kāi)一次憔购,如果操作錯(cuò)誤還可以回滾。
AOP 面向切片編程
method swizzling? 方法替換? 基于runtime知識(shí)
Aspects? 方法勾取? (暫時(shí)無(wú)法勾類方法? 自行處理)
排序
冒泡排序:從左到右岔帽,數(shù)組中相鄰的兩個(gè)元素進(jìn)行比較玫鸟,將較大的放到后面。
for(int i=0,i<arr.count,i++){
? ? for(int j=0,j<arr.count-1-i,j++){
? ? ? ? if (a[j]>a[j+1]){交換j,j+1元素位置}//把大的移到后面
}
}
選擇排序:從第一個(gè)位置開(kāi)始比較犀勒,找出最小的屎飘,和第一個(gè)位置互換,開(kāi)始下一輪贾费。
for(int i =0,i<arr.count-1,i++){
? ? for(int j=i+1,j<arr.count,i++){
? ? ? ??if (a[i]>a[j]){交換i,j元素位置}//把大的移到后面
????}
}
交換元素位置方法:
1)臨時(shí)變量交換(最差):int temp=a; ?a=b; ?b=temp;
2)相互加減:a=a+b; ?b=a-b; ?a=a-b;
3)按位異或^(最好):a=a^b; ?b=a^b; ?a=a^b;
加密
哈希(散列)函數(shù):MD5钦购,SHA
對(duì)稱加密算法:AES(速度快,安全級(jí)別高)褂萧,DES(速度快押桃,加密大量數(shù)據(jù)),3DES(基于DES导犹,一塊數(shù)據(jù)用三種不同密鑰加密三次唱凯,加密強(qiáng)度大),RC2谎痢,RC4磕昼,RC5
非對(duì)稱加密算法:RSA,ECC舶得,D-H
MD5對(duì)輸入信息生成32個(gè)字符(128位散列值)掰烟,加密后結(jié)果不可逆,同樣數(shù)據(jù)加密結(jié)果一致。
MD5加密容易破解纫骑,用加鹽(salt)的方式蝎亚,即在要加密字符的固定位置插入隨機(jī)串再進(jìn)行加密,也不安全先馆,容易找到規(guī)律
AES 只有一個(gè)密鑰发框,加解密都用它,不安全煤墙,因?yàn)闀?huì)傳遞密鑰(明文)梅惯。加密速度快效率高,但是成本高仿野,每人需要使用不同的加密密鑰铣减,管理成本高。
RSA加密與簽名? ? 非對(duì)稱 ?公鑰私鑰是一對(duì)脚作。算法強(qiáng)度復(fù)雜葫哗,安全性高,保密性好球涛。
公鑰:加密劣针,? 驗(yàn)證 。? 公開(kāi)讓大家都可以來(lái)加密數(shù)據(jù)
私鑰:解密亿扁,? 簽名 捺典。? 簽名為了唯一標(biāo)記? ? ? ? 服務(wù)端
不可互換(原理可換,但彼此要求不同从祝,且為了安全且高效襟己,不可互換)
公鑰在客戶端,用于加密哄褒。
如:A->B發(fā)送數(shù)據(jù)稀蟋,A B都產(chǎn)生一對(duì)公鑰私鑰,A把公鑰給B呐赡,B把公鑰給A退客,A->B,A用B的公鑰加密發(fā)送給B链嘀,B用自己的私鑰解密萌狂,其他收到消息的都無(wú)法解密,只有B有私鑰可以解密怀泊。
.p12 二進(jìn)制編碼密鑰
.cer 二進(jìn)制編碼證書(shū)茫藏,公鑰
.pem base64編碼密鑰
iOS上傳應(yīng)用? fairPlay簽名
Apple ID
是應(yīng)用的唯一識(shí)別符,由team id 和 bundle id組成霹琼。
Certificates證書(shū)
創(chuàng)建它需要上傳簽名證書(shū)申請(qǐng)Certificate Signing Request务傲,可通過(guò)keychain創(chuàng)建此CSR文件凉当,其中會(huì)包含一個(gè)私鑰。? 之后在開(kāi)發(fā)者網(wǎng)站創(chuàng)建Certificate售葡。
(開(kāi)發(fā)看杭、分發(fā)、通知證書(shū))APNS:正挟伙、測(cè)
APNS證書(shū):他的CSR必須和AppleID聯(lián)系生成APNS楼雹,下載后在Keychain中打開(kāi),以.p12文件導(dǎo)出尖阔,上傳到推送服務(wù)器贮缅。此文件知道應(yīng)該推送到哪個(gè)APP
Devices
100個(gè)
Provisioning profiles 配置文件
將Apple ID,證書(shū)介却,設(shè)備聯(lián)系起來(lái)谴供,在開(kāi)發(fā)者網(wǎng)站創(chuàng)建配置文件,在Xcode內(nèi)下載筷笨。
使用:在Xcode中憔鬼,添加證書(shū)龟劲,更新配置文件胃夏,選擇想要的配置文件。
數(shù)組 鏈表
數(shù)組:數(shù)組元素在內(nèi)存上連續(xù)存放昌跌,通過(guò)下標(biāo)查找元素速度快仰禀,插入、刪除需要移動(dòng)大量元素蚕愤,比較適用于元素很少變化的情況
鏈表:鏈表元素在內(nèi)存上不是順序存儲(chǔ)答恶,鏈表需從第一個(gè)開(kāi)始一直找到需要的元素位置查找慢,插入萍诱,刪除只需對(duì)元素指針重新賦值悬嗓,效率高。
哈希表:具備數(shù)組的快速查詢的優(yōu)點(diǎn)又能融合鏈表方便快捷的增加刪除元素的優(yōu)勢(shì)
Hash 哈希 散列表
哈希表是一種特殊的數(shù)據(jù)結(jié)構(gòu)裕坊,在數(shù)組和鏈表的基礎(chǔ)上演化來(lái)包竹,具有兩者的優(yōu)點(diǎn)〖可快速定位到想要查找的記錄周瞎,而不是與表中記錄的關(guān)鍵字進(jìn)行比較來(lái)進(jìn)行查找。函數(shù)映射思想饵蒂,將記錄的存儲(chǔ)位置與記錄的關(guān)鍵字關(guān)聯(lián)起來(lái)声诸,從而快速定位查找。
如:字符串?dāng)?shù)組中退盯,查找某個(gè)字符串彼乌。?數(shù)組遍歷泻肯,時(shí)間復(fù)雜度O(n);hash查找慰照,時(shí)間復(fù)雜度O(1)软免。hash表通過(guò)映射函數(shù)f:key->address,將記錄映射到表中的存儲(chǔ)位置焚挠。
哈希算法:如MD5膏萧,SHA等。將任意長(zhǎng)度原數(shù)據(jù)映射為固定長(zhǎng)度的二進(jìn)制串蝌衔,映射規(guī)則為哈希算法(直接定址法榛泛,平方取中法,折疊法噩斟,除留取余法)
哈希值:映射結(jié)果的二進(jìn)制值為哈希值
特點(diǎn):1)結(jié)果不可逆曹锨,不可反推出原數(shù)據(jù) ?2)輸入數(shù)據(jù)敏感,原數(shù)據(jù)修改很小結(jié)果也會(huì)大不同 ?3)哈希沖突概率很小剃允,不同原數(shù)據(jù)的哈希值相同概率非常小 ?4)效率高沛简,查找,插入斥废,刪除時(shí)間復(fù)雜度O(1),需要一秒內(nèi)查找上千條數(shù)據(jù)椒楣,不需遍歷,明顯比樹(shù)快牡肉,首選哈希表
優(yōu)點(diǎn):4)
缺點(diǎn):基于數(shù)組捧灰,難于擴(kuò)展。哈希表被填滿時(shí)统锤,性能下降快毛俏,所以必須清楚要存儲(chǔ)的數(shù)據(jù)量或者定期把數(shù)據(jù)移到更大的哈希表中。
hash表空間遠(yuǎn)大于實(shí)際存儲(chǔ)數(shù)據(jù)饲窿,造成空間浪費(fèi)煌寇,但是空間過(guò)小會(huì)造成哈希沖突。因此hash表的大小的確定逾雄,在不知道存儲(chǔ)個(gè)數(shù)的情況下阀溶,需要?jiǎng)討B(tài)維護(hù)hash表容量,此時(shí)可能需要重新計(jì)算hash地址嘲驾。
哈希沖突:因?yàn)槲覀兪怯脭?shù)組大小對(duì)哈希值進(jìn)行取模淌哟,有可能不同鍵值所得到的索引值相同,這里就是沖突辽故。(即不同的值存在相同索引下的位置造成沖突)
解決:1)開(kāi)放定址法:哈希算法映射出的哈希值相同時(shí)徒仓,如果此位置已經(jīng)存值,則向下尋找為空的位置存放 2)鏈地址法:采用數(shù)組與鏈表相結(jié)合的數(shù)據(jù)結(jié)構(gòu)誊垢,將相同hash地址的記錄存入一張線性表中掉弛,表頭序號(hào)為計(jì)算得到的hash地址症见,數(shù)組元素為鏈表結(jié)構(gòu),存入地址相同的記錄殃饿,查找時(shí)找到位置谋作,再便利鏈表找到需要的記錄。
應(yīng)用:找出兩文件中的重復(fù)元素乎芳,出現(xiàn)次數(shù)最多元素遵蚜,濾重。(iOS自帶NSMutableSet/NSSet濾重)
iOS消息轉(zhuǎn)發(fā)機(jī)制
調(diào)用方法不存在奈惑,可以給當(dāng)前對(duì)象添加該方法? 或者可以在運(yùn)行期給類添加該方法(類的消息轉(zhuǎn)發(fā)機(jī)制)
消息轉(zhuǎn)發(fā)是運(yùn)行時(shí)進(jìn)行吭净,兩階段:
1)檢查接收者,看是否可通過(guò)runtime動(dòng)態(tài)添加一個(gè)方法
2)完整的消息轉(zhuǎn)發(fā)機(jī)制肴甸,先檢查是否有其他對(duì)象可以處理該消息寂殉,若沒(méi)有,就把該消息的全部信息封裝到NSInvocation對(duì)象中原在,看此對(duì)象是否可以處理友扰,若還是如法處理,就查看繼承樹(shù)的類是否能夠處理庶柿,如果到NSObject之前都無(wú)法處理該消息村怪,那么最后會(huì)調(diào)用NSObject類的doesNotRecognizeSelector來(lái)拋出異常,表示嗲用的方法不對(duì)
1.動(dòng)態(tài)方法解析
對(duì)象收到無(wú)法處理的方法澳泵,會(huì)調(diào)用下面的方法
// 類方法專用
+ (BOOL)resolveClassMethod:(SEL)sel
// 對(duì)象方法專用
(BOOL)resolveInstanceMethod:(SEL)sel
在此方法中实愚,需給對(duì)象所屬類動(dòng)態(tài)添加一個(gè)方法,并返回YES兔辅,表明可以處理
2.第一步后,方法還是無(wú)法處理击喂,則會(huì)調(diào)用下面方法维苔,查詢是否有其他對(duì)象可以處理該消息
(id)forwardingTargetForSelector:(SEL)aSelector
重定向方法,需返回一個(gè)能處理該消息的對(duì)象
3.前兩步后懂昂,還是無(wú)法處理消息介时,那么會(huì)做最后嘗試,先調(diào)用methodSignatureForSelector:獲取簽名凌彬,然后forwardInvocation:進(jìn)行處理(繼承樹(shù)中)沸柔,這一步可直接轉(zhuǎn)發(fā)給其他對(duì)象,同第二步铲敛,但很少人這樣做(因?yàn)橄⑻幚碓娇亢髣t處理消息的成本越大褐澎,性能開(kāi)銷越大)所以這種方式下會(huì)改變消息內(nèi)容,比如增加參數(shù)伐蒋,改變選擇子等工三。
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
- (void)forwardInvocation:(NSInvocation *)anInvocatio
category和extension
extension看起來(lái)很像一個(gè)匿名的category迁酸,但是extension和有名字的category幾乎完全是兩個(gè)東西。 extension在編譯期決議俭正,它就是類的一部分奸鬓,在編譯期和頭文件里的@interface以及實(shí)現(xiàn)文件里的@implement一起形成一個(gè)完整的類,它伴隨類的產(chǎn)生而產(chǎn)生掸读,亦隨之一起消亡串远。extension一般用來(lái)隱藏類的私有信息,你必須有一個(gè)類的源碼才能為一個(gè)類添加extension儿惫,所以你無(wú)法為系統(tǒng)的類比如NSString添加extension抑淫。
但是category則完全不一樣,它是在運(yùn)行期決議的姥闪。
就category和extension的區(qū)別來(lái)看始苇,我們可以推導(dǎo)出一個(gè)明顯的事實(shí),extension可以添加實(shí)例變量筐喳,而category是無(wú)法添加實(shí)例變量的(因?yàn)樵谶\(yùn)行期催式,對(duì)象的內(nèi)存布局已經(jīng)確定,如果添加實(shí)例變量就會(huì)破壞類的內(nèi)部布局避归,這對(duì)編譯型語(yǔ)言來(lái)說(shuō)是災(zāi)難性的)荣月。
category中使用@property
使用@property可以讓編譯器自動(dòng)幫我們生成實(shí)例變量的setter/getter方法的聲明,方法實(shí)現(xiàn)需要在分類中自己實(shí)現(xiàn)梳毙,如果主類的成員變量在.h哺窄,則直接在分類實(shí)現(xiàn)setter,getter方法即可;如果主類的成員變量在.m账锹,則需要使用關(guān)聯(lián)對(duì)象實(shí)現(xiàn)萌业。
@protocol中使用@property
在@protocol中使用@property在編譯階段,編譯器會(huì)自動(dòng)幫我們加上setter/getter的聲明奸柬,但是實(shí)現(xiàn)還是需要采用該協(xié)議的類去寫(xiě)生年。因此在協(xié)議中使用@property主要是希望采用該協(xié)議的類能夠?qū)崿F(xiàn)該屬性
響應(yīng)鏈
iOS手指按下到松開(kāi)經(jīng)歷了什么
點(diǎn)擊屏幕,封裝為IOHIDEvent對(duì)象(IOKit.framework)——match port轉(zhuǎn)發(fā)SpringBoard(SpringBoard.app)——轉(zhuǎn)發(fā)給當(dāng)前APP的主線程(xxx.app進(jìn)程)——RunLoop的Source1觸發(fā)廓奕,監(jiān)聽(tīng)特定的match port消息( APPDelegate)——Source0回調(diào)抱婉,sendEvent:(UIApplication)——根據(jù)UIEvent的UITouch確定hitTest view 和pointInside:withEvent:和gestureRecognizers(UIWindow)——兩者識(shí)別后不再收到此UITouch事件——gestureRecognizers識(shí)別后target的action觸發(fā),事件響應(yīng)桌粉;hitTest view不響應(yīng)四個(gè)方法(began,moved,ended,cancelled)蒸绩,UITouch會(huì)沿著responderChain向上傳遞,直到UIApplication铃肯,被吃掉——事件響應(yīng)完畢患亿,主線程的RunLoop開(kāi)始睡眠,等待下一個(gè)事件缘薛。
在iOS中只有繼承了UIResponder的對(duì)象才能接收并處理事件稱為響應(yīng)者對(duì)象
UIApplication,UIViewController,UIView都繼承自UIResponder,因此他們都是響應(yīng)者對(duì)象, 都能夠接收并處理事件窍育。(button)
第一響應(yīng)者(First responder)指的是當(dāng)前接受觸摸的響應(yīng)者對(duì)象(通常是一個(gè)UIView對(duì)象)卡睦,即表示當(dāng)前該對(duì)象正在與用戶交互,它是響應(yīng)者鏈的開(kāi)端漱抓。整個(gè)響應(yīng)者鏈和事件分發(fā)的使命都是找出第一響應(yīng)者表锻。
iOS系統(tǒng)檢測(cè)到手指觸摸(Touch)操作時(shí)會(huì)將其打包成一個(gè)UIEvent對(duì)象,并放入當(dāng)前活動(dòng)Application的事件隊(duì)列乞娄,單例的UIApplication會(huì)從事件隊(duì)列中取出觸摸事件并傳遞給單例的UIWindow來(lái)處理瞬逊,UIWindow對(duì)象首先會(huì)使用hitTest:withEvent:方法尋找此次Touch操作初始點(diǎn)所在的視圖(View),即需要將觸摸事件傳遞給其處理的視圖仪或,這個(gè)過(guò)程稱之為hit-test view确镊。
UIWindow實(shí)例對(duì)象會(huì)首先在它的內(nèi)容視圖上調(diào)用hitTest:withEvent:,此方法會(huì)在其視圖層級(jí)結(jié)構(gòu)中的每個(gè)視圖上調(diào)用pointInside:withEvent:(該方法用來(lái)判斷點(diǎn)擊事件發(fā)生的位置是否處于當(dāng)前視圖范圍內(nèi)范删,以確定用戶是不是點(diǎn)擊了當(dāng)前視圖)蕾域,如果pointInside:withEvent:返回YES,則繼續(xù)逐級(jí)調(diào)用到旦,直到找到touch操作發(fā)生的位置旨巷,這個(gè)視圖也就是要找的hit-test view。
UIWindow對(duì)象以消息的形式將事件發(fā)送給第一響應(yīng)者添忘,使其有機(jī)會(huì)首先處理事件采呐。如果第一響應(yīng)者沒(méi)有進(jìn)行處理,系統(tǒng)就將事件(通過(guò)消息)傳遞給響應(yīng)者鏈中的下一個(gè)響應(yīng)者搁骑,看看它是否可以進(jìn)行處理斧吐。
注:
hitTest:withEvent:未找到第一響應(yīng)者,或第一響應(yīng)者及響應(yīng)者鏈上到UIWindow和UIApplication都不能處理仲器,則此事件會(huì)被丟棄煤率;
hitTest:withEvent:會(huì)忽略的有(hidden=YES,userInteractionEnabled=YES,alpha<0.01以及子視圖超過(guò)父視圖部分被觸摸)(父視圖的clipsToBounds 屬性為NO)。
delegate調(diào)用過(guò)程
const ?static ?extern
const是只讀的意思娄周,只在聲明中使用
static規(guī)定作用域和存儲(chǔ)方式涕侈。對(duì)于全局變量,作用域?yàn)樵诖宋募锌梢?jiàn)煤辨,對(duì)于static函數(shù)也是在當(dāng)前模塊內(nèi)函數(shù)可見(jiàn);對(duì)于局部變量木张,static規(guī)定其為靜態(tài)存儲(chǔ)方式众辨,每次調(diào)用的初始值為上次調(diào)用的值,調(diào)用結(jié)束后存儲(chǔ)空間不釋放舷礼。即讓局部變量只初始化一次鹃彻,在程序中只有一份內(nèi)存,延長(zhǎng)局部變量的生命周期妻献,程序結(jié)束才銷毀蛛株。
static const,既是只讀的,又是只在當(dāng)前模塊中可見(jiàn)的团赁,兩者的合集。例如:定義一個(gè)只能在當(dāng)前文件訪問(wèn)的全局常量?static NSString * const test = @"abc";
extern 主要用來(lái)修飾全局變量谨履,原理為先在本文件中查找欢摄,查不到再到其他文件查找。例如:常把extern和const聯(lián)合使用在項(xiàng)目中創(chuàng)建一個(gè)文件笋粟,這個(gè)文件文件中包含整個(gè)項(xiàng)目中都能訪問(wèn)的全局常量怀挠。extern?NSString * const NOTIFICATION_NAME;
static修飾全局變量后,再用extern修飾害捕,全局變量的作用域依然是此文件內(nèi)使用绿淋,不會(huì)因extern改變。
MRC下的實(shí)現(xiàn) 重寫(xiě)setter getter方法
@property(nonatomic,strong)NSString*name;
//一旦重寫(xiě)了getter.setter方法,
//必須使用@synthesize variable = _variable來(lái)區(qū)分屬性名與方法名
@synthesize name=_name;//對(duì)應(yīng)方法 ?
給成員變量重新命名 ?1)如果指定了成員變量的名稱,會(huì)生成一個(gè)指定的名稱的成員變量, ?2)如果這個(gè)成員已經(jīng)存在了就不再生成了. 3)如果是?@synthesize foo尝盼,沒(méi)有指定成員變量的名稱會(huì)自動(dòng)生成一個(gè)屬性同名的成員變量
不會(huì)自動(dòng)合成成員變量的情況:1)同時(shí)重寫(xiě)了 setter 和 getter 時(shí) 2)重寫(xiě)了只讀屬性的 getter 時(shí) 3)使用了 @dynamic 時(shí) 4)在 @protocol 中定義的所有屬性 ?5)在 category 中定義的所有屬性 6)重載的屬性(當(dāng)你在子類中重載了父類中的屬性吞滞,你必須 使用?@synthesize?來(lái)手動(dòng)合成ivar)
手動(dòng)重寫(xiě)setter和getter方法,則系統(tǒng)不會(huì)生成成員變量盾沫,兩種處理1)手動(dòng)創(chuàng)建成員變量裁赠,.m文件添加_foo的成員變量 2)使用@synthesize foo = _foo;?,關(guān)聯(lián) @property 與 ivar
-(void)setName:(NSString*)name{
????if(_name!=name){
????????[_name release];
????????_name=[name retain];
? ? }
}
-(NSString*)name{ ?return ?_name; }
生命周期
淺拷貝 深拷貝
淺拷貝:不拷貝對(duì)象本身疮跑,只拷貝指向?qū)ο蟮闹羔?/p>
深拷貝:直接拷貝整個(gè)對(duì)象內(nèi)存到另一個(gè)內(nèi)存
“=”號(hào)賦值的對(duì)象组贺,基本都是淺復(fù)制,內(nèi)存地址一樣祖娘。
NSObject對(duì)象要使用copy失尖,mutableCopy窟蓝,類必須實(shí)現(xiàn)NSCopying 或NSMutableCopying協(xié)議蟀苛,只是一般系統(tǒng)容器類已經(jīng)實(shí)現(xiàn)了這些方法奖蔓。
原則:“修改新(舊)對(duì)象沮榜,不影響舊(新)對(duì)象”
copy:創(chuàng)建的是不可變副本
mutableCopy:創(chuàng)建的是可變副本
使用copy胸完,mutableCopy是淺拷貝還是深拷貝伤为?是否會(huì)創(chuàng)建新對(duì)象啊送?遵守原則隅茎,由程序運(yùn)行環(huán)境造成鞠眉。
copy的內(nèi)存管理:
淺不產(chǎn)生新對(duì)象薯鼠,所以系統(tǒng)會(huì)的以前的對(duì)象進(jìn)行一次retain
深會(huì)產(chǎn)生新對(duì)象,系統(tǒng)不對(duì)對(duì)以前的對(duì)象進(jìn)行retain
用?@property?聲明 NSString械蹋、NSArray出皇、NSDictionary 經(jīng)常使用 copy 關(guān)鍵字,是因?yàn)樗麄冇袑?duì)應(yīng)的可變類型:NSMutableString哗戈、NSMutableArray郊艘、NSMutableDictionary,他們之間可能進(jìn)行賦值操作,為確保對(duì)象中的字符串值不會(huì)無(wú)意間變動(dòng)纱注,應(yīng)該在設(shè)置新屬性值時(shí)拷貝一份畏浆。
copy與block的配合使用:
block默認(rèn)存儲(chǔ)在棧中,棧中的block訪問(wèn)到的外界對(duì)象狞贱,不進(jìn)行retain
block若在堆中刻获,block訪問(wèn)了外界的對(duì)象,會(huì)對(duì)外界對(duì)象進(jìn)行一次retain
因block執(zhí)行時(shí)間不確定斥滤,若block里的外界對(duì)象被提前釋放将鸵,這時(shí)block執(zhí)行了,會(huì)造成野指針佑颇,崩潰顶掉,所以一般用copy關(guān)鍵字修飾block。
使用copy保存block挑胸,可保住block中痒筒,避免在block調(diào)用時(shí),外界的對(duì)象已經(jīng)被釋放茬贵。
copy strong retain weak assign
區(qū)別在于是否開(kāi)辟內(nèi)存簿透?是否對(duì)內(nèi)存地址有引用計(jì)數(shù)增加?property修飾符是在被賦值時(shí)起作用
eg:NSMuatbleString? 非容器可變變量(還有3種情況)
copy:開(kāi)辟內(nèi)存解藻,并指向(指向新內(nèi)存)老充,引用計(jì)數(shù)不加
strong:地址不變,并指向螟左,引用計(jì)數(shù)+1
weak:地址不變啡浊,指向,但是不會(huì)增加計(jì)數(shù),為0時(shí)weak會(huì)將內(nèi)存值設(shè)為nil
注:初始化和設(shè)為nil都可以將指針?biāo)赶虻臄?shù)據(jù)地址引用計(jì)數(shù)減少1
(引用計(jì)數(shù)為0則釋放)
結(jié)論:copy會(huì)重新開(kāi)辟新的內(nèi)存來(lái)保存一份相同的數(shù)據(jù)胶背。被賦值對(duì)象和原值修改互不影響巷嚣。strong和weak雖然都指向原來(lái)數(shù)據(jù)地址,原值修改的時(shí)候storng和weak會(huì)隨之變化钳吟。區(qū)別是前者會(huì)對(duì)數(shù)據(jù)地址進(jìn)行引用計(jì)數(shù)+1防止原地址值被釋放廷粒,但后者不會(huì),當(dāng)其他值都不在指向值地址時(shí)红且,值地址被釋放坝茎,weak的值也就是為nil了。我們稱會(huì)對(duì)數(shù)據(jù)地址增加引用計(jì)數(shù)的為強(qiáng)引用暇番,不改變引用計(jì)數(shù)的為弱引用
assign:同weak景东,指向但計(jì)數(shù)不增加,為0時(shí)不會(huì)將內(nèi)存值設(shè)為nil奔誓,內(nèi)存未被重寫(xiě)前依舊可以輸出, 但一旦被重寫(xiě)將崩潰
retain:同strong,ARC之后帶出了strong和weak厨喂,之前只有retain和措,copy,assign
eg:NSMutableArray 容器可變變量
結(jié)論:容器可變變量中容器本身和非容器可變變量是一樣的蜕煌,copy深拷貝派阱,strongMArr,weakMArr和assign都是淺拷貝
容器可變變量中的數(shù)據(jù)在拷貝的時(shí)候都是淺拷貝
eg:NSString? 非容器不變變量
結(jié)論:非容器不可變量除了copy其他特性同非容器可變變量,copy是淺拷貝斜纪。因?yàn)椴豢勺兞康闹挡粫?huì)改變贫母,所以不用再開(kāi)辟地址
eg:NSArray? 不可變?nèi)萜髯兞?/p>
結(jié)論:容器本身都是淺拷貝包括copy,同NSString盒刚,容器里面的數(shù)據(jù)都是淺拷貝腺劣,同NSMutableArray
結(jié)論:
可變變量中,copy是重新開(kāi)辟一個(gè)內(nèi)存因块,strong橘原,weak,assgin后三者不開(kāi)辟內(nèi)存涡上,只是指針指向原來(lái)保存值的內(nèi)存的位置趾断,storng指向后會(huì)對(duì)該內(nèi)存引用計(jì)數(shù)+1,而weak吩愧,assgin不會(huì)芋酌。weak,assgin會(huì)在引用保存值的內(nèi)存引用計(jì)數(shù)為0的時(shí)候值為空雁佳,并且weak會(huì)將內(nèi)存值設(shè)為nil脐帝,assign不會(huì),assign在內(nèi)存沒(méi)有被重寫(xiě)前依舊可以輸出甘穿,但一旦被重寫(xiě)將出現(xiàn)奔潰
不可變變量中腮恩,因?yàn)橹当旧聿豢杀桓淖儯琧opy沒(méi)必要開(kāi)辟出一塊內(nèi)存存放和原來(lái)內(nèi)存一模一樣的值温兼,所以內(nèi)存管理系統(tǒng)默認(rèn)都是淺拷貝秸滴。其他和可變變量一樣,如weak修飾的變量同樣會(huì)在內(nèi)存引用計(jì)數(shù)為0時(shí)變?yōu)閚il募判。
容器本身遵守上面準(zhǔn)則荡含,但容器內(nèi)部的每個(gè)值都是淺拷貝
delegate應(yīng)使用weak或assign 不用strong
防止循環(huán)引用。c.delegate=b時(shí)届垫,若用strong修飾释液,其實(shí)是對(duì)b的引用計(jì)數(shù)+1。
SDWebImage
1.提供一個(gè)UIImageView的category用來(lái)加載網(wǎng)絡(luò)圖片装处,并對(duì)網(wǎng)絡(luò)圖片的緩存進(jìn)行管理
2.異步下載網(wǎng)絡(luò)圖片
3.采用異步方式误债,使用memory+disk來(lái)緩存網(wǎng)絡(luò)圖片浸船,自動(dòng)管理緩存
4.同一個(gè)URL不會(huì)被重復(fù)下載(把對(duì)應(yīng)的事件以字典的方式存儲(chǔ)到內(nèi)存,放置重復(fù)發(fā)送下載圖片的請(qǐng)求),失效URL不會(huì)被無(wú)限重試(失效URL被加入列表寝蹈,所以不會(huì)重復(fù)請(qǐng)求)
5.耗時(shí)操作在子線程李命,不堵塞主線程
1)先去內(nèi)存緩存查找,
2)沒(méi)有再根據(jù)URL生成key箫老,去磁盤(pán)緩存查找(磁盤(pán)查找用NSOperation操作封字,根據(jù)key在磁盤(pán)目錄下查找圖片文件,如查到加入內(nèi)存耍鬓,空閑內(nèi)存過(guò)小先清內(nèi)存)阔籽,(保存一周會(huì)清理)key是圖片地址即:圖片URL(圖片緩存實(shí)質(zhì)是用圖片的URL進(jìn)行MD5加密后+. +URL的擴(kuò)展名組合作為圖片緩存的文件名)
3)還沒(méi)有再去下載,采用多線程異步下載牲蜀,使用NSOperation設(shè)置最大并發(fā)數(shù)笆制,
4)下載完成后對(duì)圖片進(jìn)行解碼處理,在NSOperationQueue內(nèi)處理各薇,
5)解碼完成回調(diào)代理项贺,主線程展示圖片,內(nèi)存緩存硬盤(pán)緩存同時(shí)保存(寫(xiě)入硬盤(pán)也要有用NSInvocationOperation)峭判,
6)初始化是注冊(cè)各種通知內(nèi)存警告或退到后臺(tái)時(shí)清理內(nèi)存緩存开缎,應(yīng)用結(jié)束清理過(guò)期圖片
1.入口setImageWithURL:placeholderImage:options:會(huì)先把placeholderImage 顯示,然后 SDWebImageManager 根據(jù) URL 開(kāi)始處理圖片林螃。
2.進(jìn)入SDWebImageManager-downloadWithURL:delegate:options:userInfo:交給 SDImageCache從緩存查找圖片是否已經(jīng)下載queryDiskCacheForKey:delegate:userInfo:
3.先從內(nèi)存圖片緩存查找是否有圖片奕删,如果內(nèi)存中已經(jīng)有圖片緩存,SDImageCacheDelegate 回調(diào)imageCache:didFindImage:forKey:userInfo:到 SDWebImageManager疗认。
4.SDWebImageManagerDelegate 回調(diào)webImageManager:didFinishWithImage:到UIImageView+WebCache 等前端展示圖片完残。
5.如果內(nèi)存緩存中沒(méi)有,生成 NSInvocationOperation 添加到隊(duì)列開(kāi)始從硬盤(pán)查找圖片是否已經(jīng)緩存横漏。
6.根據(jù) URLKey 在硬盤(pán)緩存目錄下嘗試讀取圖片文件谨设。這一步是在 NSOperation進(jìn)行的操作,所以回主線程進(jìn)行結(jié)果回調(diào)notifyDelegate:
7.如果上一操作從硬盤(pán)讀取到了圖片缎浇,將圖片添加到內(nèi)存緩存中(如果空閑內(nèi)存過(guò)小扎拣,會(huì)先清空內(nèi)存緩存)。SDImageCacheDelegate回調(diào)imageCache:didFindImage:forKey:userInfo:進(jìn)而回調(diào)展示圖片素跺。
8.如果從硬盤(pán)緩存目錄讀取不到圖片二蓝,說(shuō)明所有緩存都不存在該圖片,需要下載圖片指厌,回調(diào)imageCache:didNotFindImageForKey:userInfo:
9.共享或重新生成一個(gè)下載器 SDWebImageDownloader 開(kāi)始下載圖片刊愚。
10.圖片下載由 NSURLConnection 來(lái)做,實(shí)現(xiàn)相關(guān) delegate 來(lái)判斷圖片下載中踩验、下載完成和下載失敗鸥诽。
11.connection:didReceiveData:中利用 ImageIO 做了按圖片下載進(jìn)度加載效果商玫。
12.connectionDidFinishLoading:數(shù)據(jù)下載完成后交給 SDWebImageDecoder 做圖片解碼處理。
13.圖片解碼處理在一個(gè) NSOperationQueue 完成衙传,不會(huì)拖慢主線程 UI决帖。如果有需要對(duì)下載的圖片進(jìn)行二次處理,最好也在這里完成蓖捶,效率會(huì)好很多。
14.在主線程notifyDelegateOnMainThreadWithInfo:宣告解碼完成扁远,imageDecoder:didFinishDecodingImage:userInfo:回調(diào)給 SDWebImageDownloader俊鱼。
15.imageDownloader:didFinishWithImage:回調(diào)給 SDWebImageManager 告知圖片下載完成。
16.通知所有的 downloadDelegates 下載完成畅买,回調(diào)給需要的地方展示圖片并闲。
17.將圖片保存到 SDImageCache 中,內(nèi)存緩存和硬盤(pán)緩存同時(shí)保存谷羞。寫(xiě)文件到硬盤(pán)也在以單獨(dú) NSInvocationOperation 完成帝火,避免拖慢主線程。
18.SDImageCache 在初始化的時(shí)候會(huì)注冊(cè)一些消息通知湃缎,在內(nèi)存警告或退到后臺(tái)的時(shí)候清理內(nèi)存圖片緩存犀填,應(yīng)用結(jié)束的時(shí)候清理過(guò)期圖片。
19.SDWebImage 也提供了UIButton+WebCache 和 MKAnnotationView+WebCache嗓违,方便使用九巡。
20.SDWebImagePrefetcher 可以預(yù)先下載圖片,方便后續(xù)使用蹂季。
曝光量統(tǒng)計(jì)冕广,偏移量
- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath{
? ? UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell" forIndexPath:indexPath];
? ? cell.textLabel.text=_dataArray[indexPath.row];
? ? if (tableView.contentOffset.y == 0 && cell.frame.origin.y < self.view.frame.size.height) {//剛加載出來(lái)時(shí)
? ? ? ? NSLog(@"+++++++ %@",_dataArray[indexPath.row]);
? ? }else if(tableView.contentOffset.y!=0) {//上下滑動(dòng)時(shí)
? ? ? ? NSLog(@"+++++++ %@",_dataArray[indexPath.row]);
? ? }
? ? returncell;
}
預(yù)加載問(wèn)題,觸發(fā)時(shí)機(jī)
collectionView:(UICollectionView*)collectionView willDisplayCell:(UICollectionViewCell*)cell forItemAtIndexPath:(NSIndexPath*)indexPath或者scrollViewDidScroll中判斷是否還有更多數(shù)據(jù)偿洁,否則再去預(yù)加載
注:如果已經(jīng)觸發(fā)預(yù)加載撒汉,上次網(wǎng)絡(luò)正在請(qǐng)求時(shí),又一次觸發(fā)請(qǐng)求則取消第二次涕滋,防止重復(fù)請(qǐng)求睬辐。
應(yīng)用間跳轉(zhuǎn)實(shí)現(xiàn) 遵守哪些協(xié)議
A->B ?A跳轉(zhuǎn)到B
B可以被其他app調(diào)起的條件:手機(jī)安裝B;B注冊(cè)了自己的URL Scheme協(xié)議(唯一標(biāo)識(shí))(info.plist中URL types里添加)
A可以調(diào)起其他app的條件:手機(jī)安裝A何吝;A添加了被跳轉(zhuǎn)方的scheme白名單(info.plist中LSAplicationQueriesScheme里添加)溉委;A添加了調(diào)起代碼
馬甲包上架
為代碼虛擬化,字符串加密爱榕,代碼符號(hào)邏輯混淆瓣喊,防范編譯,防調(diào)試防篡改等深度混淆整體加固加密保護(hù)黔酥,
防止應(yīng)用程序遭到逆向破解藻三,二次打包簽名洪橘。防止使用逆向編譯工具反編譯出核心代碼后被竊取,程序邏輯破解棵帽,惡意篡改代碼及文件進(jìn)行盜版和植入廣告等二次打包和重簽名行為熄求,API接口暴露,攔截請(qǐng)求惡意攻擊服務(wù)端逗概,篡改接口數(shù)據(jù)重復(fù)請(qǐng)求
OC與Swift的區(qū)別
Swift:容易閱讀弟晚,結(jié)構(gòu)簡(jiǎn)單,文件沒(méi)有了.h.m逾苫,類型安全卿城,速度快,運(yùn)行性能高
swift是oc上提出的铅搓,有oc沒(méi)有的類瑟押,如:元組,有泛型
swift定義的常量與變量是沒(méi)有值的星掰,所以引入了optional可選概念多望,若沒(méi)有值,就用optional氢烘,比OC中指針設(shè)為nil安全
swift的怀偷?和!用來(lái)標(biāo)記變量是否可選威始,枢纠!表示可選變量必須保證轉(zhuǎn)換能夠成功,黎棠?轉(zhuǎn)換不成功不報(bào)錯(cuò)晋渺,會(huì)設(shè)為nil,如果轉(zhuǎn)化成功要使用該變量需要后面加!修飾脓斩。
swift let聲明的常量不可變木西,var聲明的變量可以改變
swift中繼承里寫(xiě)final防止被重寫(xiě),as類型的轉(zhuǎn)換
OC:OC動(dòng)態(tài)性語(yǔ)言随静,將數(shù)據(jù)類型的確定由編譯時(shí)推遲到運(yùn)行時(shí)八千,swift是靜態(tài)行語(yǔ)言
bugly里面經(jīng)常崩潰的點(diǎn) 如何避免 一次性避免
小廣播語(yǔ)音上傳壓縮 加密
藍(lán)牙開(kāi)發(fā)
一般來(lái)說(shuō)我們使用的iPhone都是做centralManager的,藍(lán)牙模塊是peripheral的燎猛,所以我們是want datas恋捆,需要接受數(shù)據(jù)。
1.判斷狀態(tài)為powerOn重绷,然后執(zhí)行掃描
2.停止掃描沸停,連接外設(shè)
3.連接成功,尋找服務(wù)
4.在服務(wù)里尋找特征
5.為特征添加通知
5.通知添加成功昭卓,那么就可以實(shí)時(shí)的讀取value[也就是說(shuō)只要外設(shè)發(fā)送數(shù)據(jù)[一般外設(shè)的頻率為10Hz]愤钾,代理就會(huì)調(diào)用此方法]瘟滨。
6.處理接收到的value,[hex值能颁,得轉(zhuǎn)換] 之后就自由發(fā)揮了杂瘸,在這期間都是通過(guò)代理來(lái)實(shí)現(xiàn)的,也就是說(shuō)你只需要處理你想要做的事情伙菊,代理會(huì)幫你調(diào)用方法败玉。[別忘了添加代理]
注意:
不是每個(gè)特征都可以通過(guò)回調(diào)函數(shù)查看寫(xiě)入狀態(tài)的。如:immediateAlertService的alertLevelCharacteristic占业,不能使用普通CBCharacteristicWriteType.WithRespons來(lái)寫(xiě)入绒怨,只能用CBCharacteristicWriteType.WithOutRespons,這樣就可以通過(guò)回調(diào)函數(shù)查看每一個(gè)Characteristic的狀態(tài)檢查谦疾。
iOS中當(dāng)發(fā)生讀寫(xiě)交互時(shí),系統(tǒng)才會(huì)和外設(shè)進(jìn)行綁定操作犬金。
想獲取藍(lán)夜的廣播包didDiscoverPeripheral:advertisementData:方法的advertisementData并非廣播包念恍,應(yīng)讓硬件將數(shù)據(jù)寫(xiě)入kCBAdvDataManufacturerData字段里。