1、監聽導航欄的frame 和 屏幕旋轉起沖突,會崩潰
// 監聽導航欄的frame
[self.navigationController.navigationBar addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
NSNumber *num = change[@"new"];
NSLog(@"-----------------------------num = %@",num);
CGRect rect = num.CGRectValue;
self.navBar.frame = rect;
}
- (void)dealloc{
[self.navigationController.navigationBar removeObserver:self forKeyPath:@"frame"];
}
/**
* @author 孔凡列, 16-09-21 08:09:06
*
* 橫屏
*/
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
2、appDelegate 里面創建UIWindow的時候,需要指定window的frame,不然iOS8 的window的寬高會為0,但是iOS8以上就不會出現問題
self.window = [[UIWindow alloc] init];// 這樣不行
self.window = [[UIWindow alloc] initWithFrame:CGRectMake(0,0,SCREEN_WIDTH,SCREEN_HEIGHT)];// 這樣就不會出現適配問題
3、AVAudioPlayer播放聲音的時候,設置volume 為 1.0 后還是超級小聲,超過1.0就會失真.添加一句代碼可完美解決
[[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil];
4、監聽橫豎屏旋轉,系統通知
UIDeviceOrientationDidChangeNotification
5、swift NSObject 的方法都不適用了,很多都是struct 不是 class
String 是struct 屬于 Any 不是 AnyObject,所以iskind 不能用,用is 判斷
6、iOS KVO監聽數組元素個數變化(數組地址改變、插入、刪除、替換)
- 需要 用
mutableArrayValueForKey
獲取到的可變數組(網上說控制器的數組沒辦法監聽,其實可以的,只是一定要用mutableArrayValueForKey
) - 還有一個注意點:分類中的數組是沒辦法監聽到的,其他都可以
7、iOS 系統字體
[UIFont systemFontSize];// 系統默認字體大小 14
[UIFont smallSystemFontSize];// 小系統字體大小 12
[UIFont labelFontSize];// 系統label字體大小 17
[UIFont buttonFontSize];// 系統button字體大小 18
8、typeof(self) strongSelf = weakSelf; 的使用解答地址
總結
1、 在 Block 內如果需要訪問 self 的方法、變量,建議使用 weakSelf。
2 、如果在 Block 內需要多次 訪問 self,則需要使用 strongSelf。此時self不會被釋放,當block執行完后,會自動釋放該strongSelf
9、layoutSubviews 什么時候調用?drawRect 什么時候調用?
視圖的內容需要重繪時可以調用
setNeedsDisplay
方法,該方法會設置該視圖的displayIfNeeded
變量為 YES ,NSRunLoop 在下一次循環檢中測到該值為 YES 則會自動調用drawRect
進行重繪。視圖的內容沒有變化,但在父視圖中位置變化了可以調用
setNeedsLayout
,該方法會設置該視圖的layoutIfNeeded
變量為YES,NSRunLoop 在下一次循環檢中測到該值為 YES 則會自動調用layoutSubViews
進行重繪。
10、AFN3.0 支持ipv6,代碼配置
11、取狀態欄判斷網絡狀態
注意:飛行模式和關閉移動網絡都拿不到dataNetworkType;1 - 2G; 2 - 3G; 3 - 4G; 5 - WIFI
BOOL flag = NO;
UIApplication *app = [UIApplication sharedApplication];
NSArray *children = [[[app valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews];
int netType = 0;
//獲取到網絡返回碼
for (id child in children) {
NSLog(@"child = %@",NSStringFromClass([child class]));
if ([child isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")]) {
//獲取到狀態欄,飛行模式和關閉移動網絡都拿不到dataNetworkType;1 - 2G; 2 - 3G; 3 - 4G; 5 - WIFI
netType = [[child valueForKeyPath:@"dataNetworkType"] intValue];
switch (netType) {
case 0:
flag = NO;
//無網模式
break;
default:
flag = YES;
break;
}
}
}
12、label 文字實現豎直排布
- 只需要設置
numberOfLines = 0
然后再調用sizeToFit
13、本地搭建IPv6環境測試你的APP(OS X 10.11 新加的功能)
打開系統偏好設置-按住
option
- 點擊共享-創建NAT64
14、給 按鈕 的imageView添加動畫組
注意不能設置按鈕的
backgroundImage
否則沒動畫效果
[playBtn setImage:[UIImage imageNamed:@"voice_button_01"] forState:UIControlStateNormal];
//設置動畫圖片的資源
playBtn.imageView.animationImages = self.animateBtnArrM;
//設置動畫的持續時間
playBtn.imageView.animationDuration = 1.5;
//設置動畫的執行次數
playBtn.imageView.animationRepeatCount = MAXFLOAT;
//開始動畫
[playBtn.imageView startAnimating];
15、使用SDWebImage 加載 gif圖片 url ,不能壓縮,否則無法正常顯示
加載GIF 可以 用webView 加載,UIWebView 有緩存,WKWebView 在 iOS 9 之后才有情況緩存的接口
16、滾動視圖(UIScrollView 、UITableView、UIWebView、WKWebView、UICollectionView)界面點擊事件,添加點擊手勢需要實現其中一個代理方法,才有點擊效果
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
17、cocoapod search 不到所需的庫
-
rm ~/Library/Caches/CocoaPods/search_index.json
執行完重新 search 就行
18、設置UITextField 水印居中
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 200, 200, 30)];
textField.borderStyle = UITextBorderStyleLine;
textField.placeholder = @"hello world";
UILabel *label = [textField valueForKey:@"_placeholderLabel"];
label.textAlignment = NSTextAlignmentCenter;
[textField setValue:label forKey:@"_placeholderLabel"];
[self.view addSubview:textField];
19、優雅地隱藏顯示導航欄
- 遵守協議
<UINavigationControllerDelegate>
- 設置代理
self.navigationController.delegate = self;
- 重寫方法
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
BOOL isVC = [viewController isKindOfClass:[self class]];
[self.navigationController setNavigationBarHidden:isVC animated:YES];
}
20、OC 的 指針,swift 的表示方法:
static const void* mainQueueKey = @"mainQueue";
static void* mainQueueContext = @"mainQueue";
private let mainQueueKey = UnsafeMutablePointer<Void>.alloc(1)
private let mainQueueValue = UnsafeMutablePointer<Void>.alloc(1)
21、swift 實現KVO以及提供給OC調用
- 需要使用@dynamic 和 @objc使用,默認如果使用@dynamic swift會隱式添加@objc
22、swift 使用runtime
- 如果是純swift類,要使用runtime需要加上@dynamic,如果是直接或者間接繼承NSObject(這個還是動態執行的),就可以直接使用runtime
23、宏定義的 attribute((visibility ("default"))) 作用
visibility屬性是設置將本項目的函數作為庫使用時的可見性。g++編譯時, 加入-fvisibility=hidden參數, 會將所有默認public屬性設為hidden, 導致庫外文件不可見
如果設置了attribute((visibility ("default")))的函數, 其public屬性仍能對外可見, 而不是hidden。可見編譯指令 -fvisibility是對所有屬性符號進行處理, 而attribute((visibility ("default")))是對特定函數可見性進行設置, 避免沖突。
原文地址
24、ARC 下使用 autoreleasepool
- 如果你創建太多的臨時對象在你的代碼中,你會注意到你的內存用量會增加直到對象被釋放掉。問題是內存只有在UIKit排空(drains)自動釋放池的時候才能被釋放,這意味著內存被占用的時間超過了需要。好消息是你可以在你的@autoreleasepool段中創建臨時對象來避免上述情況
NSArray *urls = <# An array of file URLs #>;
for (NSURL *url in urls) {
@autoreleasepool {
NSError *error;
NSString *fileContents = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
/* Process the string, creating and autoreleasing more objects. */
}}
25、監聽橫豎屏切換
- 橫豎屏切換的時候,系統會響應一些函數,其中
viewWillLayoutSubviews
和viewDidLayoutSubviews
。
26、并發 和 并行的區別
并發:當有多個線程在操作時,如果系統只有一個CPU,則它根本不可能真正同時進行一個以上的線程,它只能把CPU運行時間劃分成若干個時間段,再將時間 段分配給各個線程執行,在一個時間段的線程代碼運行時,其它線程處于掛起狀。.這種方式我們稱之為并發(Concurrent)。
并行:當系統有一個以上CPU時,則線程的操作有可能非并發。當一個CPU執行一個線程時,另一個CPU可以執行另一個線程,兩個線程互不搶占CPU資源,可以同時進行,這種方式我們稱之為并行(Parallel)。
區別:并發和并行是即相似又有區別的兩個概念,并行是指兩個或者多個事件在同一時刻發生;而并發是指兩個或多個事件在同一時間間隔內發生。
例子:
1).并發 一個送外賣的A需要把兩份外賣分別送到兩個客戶B和C手里。 A必須先送完B外賣才能接著送C的。這就是并發
2).并行 客戶C 分別從餓了么和美團訂了一共兩份外賣。那么外賣員A和外賣員B需要把外賣一同送到客戶C手里。 這就是并行
27、 使用Instrument 的time profiler 調試
- 默認是不會顯示方法名,需要項目中開啟
Build Settings
->Build Options
->Debug
->DWARF with dSYM File
28、設置collectionView header 懸浮
- 設置 shouldInvalidateLayoutForBoundsChange屬性為 YES就好