1、關于AES(以AES128為例)加密的CBC模式:
秘鑰長度:
128位(16字節)
偏移量:
在CBC分組模式下每個明文塊要先與前一個密文塊進行異或后再加密,每個密文塊都依賴于前面的所有明文塊。
那么第一個明文快就要用到偏移量IV了。在CBC中,IV先與第一個明文塊進行異或,得到第一個明文塊。
填充模式:PKCS5/PKCS7
- PKCS5Padding限制了填充的Block Size為8字節(Bytes),填充塊最多只能填充8個字節(Bytes),限定了范圍,填充內容0x01-0x08;
- 當際上當分組塊大于8字節時,如AES128是16字節時,理論上數據塊分組需要補位的字節數:1-16個字節(Bytes),在AES加密當中嚴格來說是不能使用PKCS5的,因為AES的塊大小是16字節(Bytes)而PKCS5只能用于8字節(Bytes),補不齊;
- 但是,通常我們在AES加密中所說的PKCS5指的就是PKCS7,在iOS中提供了PKCS7Padding,而Java中則提供了PKCS5Padding,而Java實際上當分組塊大于8字節(Bytes)時,其PKCS5Padding與PKCS7Padding是相等的:每需要填充n個字節,每個字節填充的值是n (n的范圍實際上就是PKCS7Padding的1-255字節數的范圍)。
2、關于導航欄透明備忘錄:
iOS7之后由于navigationBar.translucent默認是YES,坐標默認在(0,0)點 ,當不透明的時候(設為NO),零點坐標在(0,64); ps:64或88
1、如果你想設成透明的,而且還要零點從(0,64)開始,那就添加:
self.edgesForExtendedLayout = UIRectEdgeNone;
2、如果你想設成不透明的,而且還要坐標從(0,0)開始,添加
self.extendedLayoutIncludesOpaqueBars = YES;
3、關于響應鏈的備忘錄:
1、如果第一響應者是自定義的UIControl的子類同時響應鏈上也綁定了手勢識別器UIGestureRecognizer:
UIWindow會將事件先發送給響應鏈上綁定的手勢識別器UIGestureRecognizer,再發送給第一響應者,如果手勢識別器能成功識別事件,UIApplication默認會向第一響應者發送cancel響應事件的命令;如果手勢識別器未能識別手勢,而此時觸摸并未結束,則停止向手勢識別器發送事件,僅向第一響應者發送事件。如果手勢識別器未能識別手勢,且此時觸摸已經結束,則向第一響應者發送end狀態的touch事件,以停止對事件的響應。
2、如果第一響應者是UIControl的子類且是系統類(UIButton、UISwitch)同時響應鏈上也綁定了手勢識別器UIGestureRecognizer:
UIWindow會將事件先發送給響應鏈上綁定的手勢識別器UIGestureRecognizer,再發送給第一響應者,如果第一響應者能響應事件,UIControl調用調用sendAction:to:forEvent:將target、action以及event對象發送給UIApplication,UIApplication對象再通過 sendAction:to:from:forEvent:向target發送action。
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
BOOL shouldInterceptTouches = YES;
CGPoint location = [self.view convertPoint:point fromView:self.targview];
CGRect rect = [self.view convertRect:self.targview.frame toView: self.view];
shouldInterceptTouches = CGRectContainsPoint(rect, location);
if (shouldInterceptTouches) {
return self.targview;
}else {
return self.view //// [super hitTest:point withEvent:event];
}
}
總結:UIControl的子類且是系統類UIButton,可以收到UIGestureRecognizer的透傳響應,
自定義的UIControl會被手勢響應攔截。
4、對大佬們<年終總結>的總結
https://onevcat.com/2021/01/2020-final/
https://blog.yuusann.com/corpus/article/21001
http://weibointl.api.weibo.com/share/194006618.html?weibo_id=4589331102307217
https://mp.weixin.qq.com/s/RLPsrxiD2ILbhLU6drvaYQ
http://blog.cnbang.net/living/3716/
https://www.roczhang.com/year-in-review-2020.html
5、oc 中 static 小tips
局部變量
1.只會被初始化一次,也就是只有一份內存。
2.生命周期被改變,一直到程序結束才釋放
- (NSMapTable *)testMap{
static NSMapTable *map = nil;
if (!map) {
map = [NSMapTable mapTableWithKeyOptions:NSMapTableCopyIn valueOptions:NSMapTableWeakMemory];
}
return map;
}
如上的寫法是,map只會初始一次
其他資料關于static說明:http://www.lxweimin.com/p/4bfd96c57a6d
6、Hook方法交換中一個常見問題
為什么很多hook交換方法看著像遞歸,無限循環調用?比如(此處轉用了其他作者文章代碼):
+ (void)sjt_exchangeSelector:(SEL)oldSel andNewSelector:(SEL)newSel {
Method oldMethod = class_getInstanceMethod([self class], oldSel);
Method newMethod = class_getInstanceMethod([self class], newSel);
// 改變兩個方法的具體指針指向
method_exchangeImplementations(oldMethod, newMethod);
}
+ (void)load {
// 該方法會在加載這個類的時候執行(APP啟動時會加載,只執行一次)
// 此處交換descriptionWithLocale:與自己寫的my_descriptionWithLocale:的方法指針
[self sjt_exchangeSelector:@selector(descriptionWithLocale:) andNewSelector:@selector(my_descriptionWithLocale:)];
}
- (NSString *)my_descriptionWithLocale:(id)locale {
NSString *desc = [self my_descriptionWithLocale:locale];
desc = [self replaceUnicode:desc];
return desc;
}
- (NSString *)replaceUnicode:(NSString *)unicodeStr {
NSString *tempStr1 = [unicodeStr stringByReplacingOccurrencesOfString:@"\\u" withString:@"\\U"];
NSString *tempStr2 = [tempStr1 stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];
NSString *tempStr3 = [[@"\"" stringByAppendingString:tempStr2] stringByAppendingString:@"\""];
NSData *tempData = [tempStr3 dataUsingEncoding:NSUTF8StringEncoding];
NSString* returnStr = [NSPropertyListSerialization propertyListFromData:tempData
mutabilityOption:NSPropertyListImmutable
format:NULL
errorDescription:NULL];
return [returnStr stringByReplacingOccurrencesOfString:@"\\r\\n" withString:@"\n"];
}
問題:你好,我想知道為什么不會造成死循環,請問是否可以解答一下?
回答:先要弄清楚selector、IMP、Method三者之間的關系,通俗的方法Method是個結構體。method_exchangeImplementations交換的是這個這個兩個方法的IMP。你代碼中看到的是[self my_descriptionWithLocale:locale],實際上執行指向了[self descriptionWithLocale:locale]實現地址的指針,執行的是descriptionWithLocale內部實現。
7、 iOS 13獲取keyWindow
@property(nullable, nonatomic,readonly) UIWindow *keyWindow
API_DEPRECATED("Should not be used for applications that support multiple scenes as it returns a key window across all connected scenes", ios(2.0, 13.0));
- (UIWindow *)getKeyWindow
{
if (@available(iOS 13.0, *))
{
for (UIWindowScene* windowScene in [UIApplication sharedApplication].connectedScenes) {
if (windowScene.activationState == UISceneActivationStateForegroundActive)
{
for (UIWindow *window in windowScene.windows)
{
if (window.isKeyWindow)
{
return window;
break;
}
}
}
}
}
else
{
return [UIApplication sharedApplication].keyWindow;
}
return nil;
}
8、大白話講TCP 為什么需要三次握手四次揮手:
1、TCP連接為什么是3次握手,不是1次、不是2次,也不是4次5次?
TCP建立有效連接的目的就是保證雙方都具備兩點能力:發送數據和接收數據。
生活場景:小明手機接通小王手機:
(第一次握手)小明:你好我是小明,你是小王嗎?聽得見我說話嗎?
(第二次握手)小王:你好小明,我是小王,我可以聽見你說話,你可以聽見我說話嗎?
(第三次握手)小明:我可以聽見你說話。
日常生活中,如果說是把上面三次對話作為調試驗證雙方手機聽筒(收數據能力)、話筒(發送數據能力)是否正常,這上面三句對話一句也不能少。
1)、如果小明說完上述第一句,也就是第一次握手就建立連接,就開始講事情,碰到小王話筒小聽壞了,小明就白講了,沒有意義的,所以1次握手不行。
2)、如果小王回復了上述第二句,也就是第二次握手就建立連接,這個時候小王的話筒是壞的(不能發送數據),這個時候小王開始講事情也是白講,因為小明根本聽不到小王說話。
3)、只有小明回復小王上述第三句,也就是第三次握手之后建立連接,這個時候,就確認了雙方的手機聽筒(收數據能力)、話筒(發送數據能力)都正常,可以正常通話了。
所以、根據這個常識,只有三次才才可以,4次、5次都是多余,三次不能少,也不必多。
2、TCP連接為什么斷開連接需要4次揮手?
這里討論的TCP斷開場景是:它已經建立了連接,現在傳輸數據的過程中。TCP是保證可靠傳輸的協議。
生活場景:小明和小王通話中,他們正在聊很重要的事情:
(第一次揮手)小明:你好小王,我有事情得掛斷了!
(第二次揮手)小王:收到,那你稍等一會,等我把最后這重要的事說下你再掛斷!
(第三次揮手)小王:你好小明,事情已經說完了,你可以掛斷了!
(第四次揮手)小明:都已收到,我馬上準備掛斷。
為了把重要的事情說完(TCP為了保證正在傳輸的數據可靠性),小王多說了一句話,把重要的事情收尾了(把正在傳輸的數據傳輸完成)。這就是從生活白話場景中可以看到斷開需要4次揮手。
另外:
1、其他的ACK、seq、FIN 等概念,都是基于這個基礎原理設計的流程控制概念,具體可以參考:
大白話告訴你 TCP 為什么需要三次握手四次揮手
2、另外關于TCP粘包、分包問題,為什么UDP和IP包沒有這樣的問題,如何解決請參考:
TCP為什么會粘包?
3、TCP等參考資料鏈接
9、UIApplicationDelegate方法調用順序(iOS 12)
傳送門:UIApplicationDelegate方法調用順序(iOS 12)