1.主線程中更新UI
之前在項(xiàng)目中的一個(gè)回調(diào)方法里面更新了UI導(dǎo)致了一個(gè)NSInternalInconsistencyException錯(cuò)誤,根據(jù)輸錯(cuò)信息大致找到錯(cuò)誤的具體情況 **Only run on the main thread! **,原因是因?yàn)樵谧泳€程中不能對(duì)UI進(jìn)行更新,如果需要更新UI必須切換到主線程中去更新。
那么在子線程中如何更新UI呢,iOS幫我們提供了一個(gè)方法叫 dispatch_async(dispatch_queue_t queue, dispatch_block_t block),可以將方法塊發(fā)送到指定的線程中執(zhí)行,dispatch_get_main_queue() 代表了主線程,這樣更新UI的代碼就可以完美執(zhí)行啦。
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Update View");
});
2.NSURLSession簡(jiǎn)單使用
自從iOS 9.0后Apple建議使用NSURLSession代替NSURLConnection。
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error) {
NSLog(@"HTTP ERROR:%@",error.localizedDescription);
}else{
NSInteger responseCode = [(NSHTTPURLResponse *)response statusCode];
NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"HttpResponseCode:%ld", (long)responseCode);
NSLog(@"HttpResponseBody %@",responseString);
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
//成功處理...
}
}] resume];
3.設(shè)置屏幕常亮
//將空閑定時(shí)器禁用,這樣屏幕就能一直保持常亮了
[UIApplication sharedApplication].idleTimerDisabled = YES;
//設(shè)置窗口亮度大小 范圍是0.1 -1.0 一般常亮后盡量把亮度調(diào)低點(diǎn),這樣能省點(diǎn)電
[[UIScreen mainScreen] setBrightness:0.5];
4.使用CocoaHTTPServer來(lái)創(chuàng)建本地web服務(wù)器
因?yàn)樽约旱捻?xiàng)目需求要通過網(wǎng)頁(yè)上傳文件到APP里面去,所以通過這個(gè)東西可以把手機(jī)臨時(shí)服務(wù)器,然后通過網(wǎng)頁(yè)上傳文件的形式將文件上傳到APP。
//主要代碼
self.httpServer = [[HTTPServer alloc]init];
[self.httpServer setType:@"_http._tcp."];
[self.httpServer setPort:8080];
NSString *webPath = [[NSBundle mainBundle] resourcePath];
[self.httpServer setConnectionClass:[MyHTTPConnection class]];
[self.httpServer setDocumentRoot:webPath];
NSError *error;
[self.httpServer start:&error];
//然后在webPath指定的目錄下面放幾個(gè)網(wǎng)頁(yè)就可以訪問啦
5.沙盒路徑獲取
Documents:蘋果建議將程序中建立的或在程序中瀏覽到的文件數(shù)據(jù)保存在該目錄下;
Library:存儲(chǔ)程序的默認(rèn)設(shè)置或其它狀態(tài)信息;
tmp:提供一個(gè)即時(shí)創(chuàng)建臨時(shí)文件的地方。
Library 目錄:這個(gè)目錄下有兩個(gè)子目錄:Caches 和 PreferencesPreferences 目錄包含應(yīng)用程序的偏好設(shè)置文件。您不應(yīng)該直接創(chuàng)建偏好設(shè)置文件,而是應(yīng)該使用NSUserDefaults類來(lái)取得和設(shè)置應(yīng)用程序的偏好
Caches 目錄用于存放應(yīng)用程序?qū)S玫闹С治募?,保存?yīng)用程序再次啟動(dòng)過程中需要的信息。
注意:
iTunes在與iPhone同步時(shí),備份所有的Documents和Library文件。
iPhone在重啟時(shí),會(huì)丟棄所有的tmp文件。
如果有路徑拼接使用 stringByAppendingPathComponent方法
//獲取家目錄路徑的函數(shù):
NSString *homeDir = NSHomeDirectory();
//Documents目錄
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
//app包路徑
[[NSBundlemainBundle]bundlePath];
//獲取tmp目錄
NSString *tempPath = NSTemporaryDirectory();
//獲取Caches目錄路徑的方法:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES);
NSString *cachesDir = [paths objectAtIndex:0];
//獲取應(yīng)用程序程序包中資源文件路徑的方法
NSString *imagePath = [[NSBundlemainBundle]pathForResource:@"apple"ofType:@"png"];
6.遍歷目錄
NSFileManager *myManage = [NSFileManager defaultManager];
NSString *docPath = [PathHelper getDocumentsPath];
NSDirectoryEnumerator *myDir = [myManage enumeratorAtPath:docPath];
while ((docPath = [myDir nextObject])!=nil) {
NSLog(@"%@========",docPath);
}
7.頁(yè)面跳轉(zhuǎn)
//從下往上推一個(gè)窗口
[self presentViewController:vc animated:YES completion:nil];
//返回上一個(gè)界面
[ self dismissViewControllerAnimated: YES completion: nil ];
//navigationController彈出窗口向左滑動(dòng)彈出
[self.navigationController pushViewController:readView animated:YES];
//返回上一頁(yè)
[self.navigationController popViewControllerAnimated:YES];
//返回到根視圖
[self.navigationController popToRootViewControllerAnimated: YES ];
8.隱藏tabbar
hidesBottomBarWhenPushed 屬性就可以了,在要隱藏tabbar之前的頁(yè)面添加
- (void)viewDidAppear:(BOOL)animated{
self.hidesBottomBarWhenPushed = YES;
}
- (void)viewWillDisappear:(BOOL)animated{
self.hidesBottomBarWhenPushed = NO;
}
//新辦法 直接設(shè)置在下一個(gè)界面跳轉(zhuǎn)的時(shí)候設(shè)置下個(gè)界面
[vc setHidesBottomBarWhenPushed:YES];
9.UITableViewCell取消選中
在didSelectRowAtIndexPath代理方法中添加
[tableView deselectRowAtIndexPath:indexPath animated:YES];
10.UITabelViewCell的寬度
Cell的寬度默認(rèn)是320,所以在做布局的時(shí)候在layoutSubViews方法中去重新布局Cell的寬度就正常了,這個(gè)layoutSubViews在Frame被修改的時(shí)候回調(diào)用一次,所以只有當(dāng)frame被設(shè)置正確的時(shí)候在去布局就OK啦
- (void)layoutSubviews{
[super layoutSubviews];
__weak typeof (self)weakSelf = self;
[self.explanationLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(weakSelf.contentView).offset(30);
make.left.equalTo(weakSelf.contentView).offset(20);
make.size.mas_equalTo(CGSizeMake(CGRectGetWidth(weakSelf.contentView.frame) - 25, 20));
}];
}
11.UIScrollView組件設(shè)置頁(yè)數(shù)
當(dāng)UIScrollView組件被設(shè)置成翻頁(yè)模式后要設(shè)置具體翻到第幾頁(yè)可以通過setContentOffset方法去設(shè)置,手動(dòng)計(jì)算偏移的坐標(biāo)
[self.scrollView setContentOffset:CGPointMake((winW* currentPage), 0)];
12.獲取當(dāng)前時(shí)間戳
[[NSDate dateWithTimeIntervalSinceNow:0]timeIntervalSince1970] * 1000;
13.修改系統(tǒng)狀態(tài)顏色
//UIBarStyleDefault or UIBarStyleBlack 兩種樣式
[self.navigationController.navigationBar setBarStyle:UIBarStyleDefault];
14.字符串分割
//不需要間隔分割字符串
NSMutableArray *arr = [[NSMutableArray alloc]init];
for (int index = 0; index < str.length; index++) {
[arr addObject:[str substringWithRange:NSMakeRange(index, 1)]];
}
//根據(jù)間隔分割字符串
NSArray *arr = [@"1.2.3.4.5.6.7" componentsSeparatedByString:@"."];
15.大小寫轉(zhuǎn)換
//轉(zhuǎn)小寫
NSString *str = [@"ABCD" lowercaseString]; // abcd
//首字母大寫
NSString *str = [@"abcd" capitalizedString]; // Abcd
//轉(zhuǎn)小寫
NSString *str1 = [@"abcd" uppercaseString];// ABCD
16.UITableView滾動(dòng)到最后一行
if (self.chatTableView.contentSize.height > self.chatTableView.frame.size.height)
{
CGPoint offset = CGPointMake(0, self.chatTableView.contentSize.height - self.chatTableView.frame.size.height);
[self.chatTableView setContentOffset:offset animated:YES];
}
17.時(shí)間處理
//實(shí)例化一個(gè)NSDateFormatter對(duì)象
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
//設(shè)定時(shí)間格式,這里可以設(shè)置成自己需要的格式
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
//用[NSDate date]可以獲取系統(tǒng)當(dāng)前時(shí)間
NSString *currentDateStr = [dateFormatter stringFromDate:[NSDate date]];
18.跳轉(zhuǎn)到系統(tǒng)WiFi設(shè)置界面
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs:root=WIFI"]];
19.JSON去掉換行
-(NSString*)ObjectTojsonString:(id)object{
NSString *jsonString = [[NSString alloc]init];
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:object options:NSJSONWritingPrettyPrinted error:&error];
if (! jsonData) {
NSLog(@"error: %@", error);
} else {
jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
NSMutableString *mutStr = [NSMutableString stringWithString:jsonString];
NSRange range = {0,jsonString.length};
[mutStr replaceOccurrencesOfString:@" "withString:@""options:NSLiteralSearch range:range];
NSRange range2 = {0,mutStr.length};
[mutStr replaceOccurrencesOfString:@"\n"withString:@""options:NSLiteralSearch range:range2];
return mutStr;
}
20.電話號(hào)碼驗(yàn)證
//驗(yàn)證電話號(hào)碼
NSString *regex = @"^[1][0-9]{10}$";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
BOOL isValid = [predicate evaluateWithObject:phone];
21. Nonnull區(qū)域設(shè)置
如果需要每個(gè)屬性或每個(gè)方法都去指定nonnull和nullable,是一件非常繁瑣的事。
蘋果為了減輕我們的工作量,專門提供了兩個(gè)宏:
NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END。
在這兩個(gè)宏之間的代碼,所有簡(jiǎn)單指針對(duì)象都被假定為nonnull,因此我們只需要去指定那些nullable的指針。
如下代碼所示:
NS_ASSUME_NONNULL_BEGIN
@interface TestNullabilityClass ()
@property (nonatomic, copy) NSArray * items;
- (id)itemWithName:(nullable NSString *)name;
@end
NS_ASSUME_NONNULL_END
22.FOUNDATION_EXPORT宏
.h文件
FOUNDATION_EXPORT NSString *const kMyConstantString;
.m文件是這樣定義的
NSString *const kMyConstantString = @"hello world";
另一種就是常用的#define 方法定義常量了
#define kMyConstantString @"Hello"
那么他們有什么區(qū)別呢?
使用FOUNDATION_EXPORT方法在檢測(cè)字符串的值是否相等的時(shí)候效率更快.
可以直接使用(myString == MyFirstConstant)來(lái)比較, 而define則使用的是([myString isEqualToString:MyFirstContant])
哪個(gè)效率更高,顯而易見了
第一種是直接比較指針地址
第二種則是一一比較字符串的每一個(gè)字符是否相等.
2.3 AssertMacros.h文件
當(dāng)條件返回false時(shí),執(zhí)行標(biāo)記以后的代碼
NSString *msg = nil;
//如果msg等于nil的時(shí)候直接跳轉(zhuǎn)到_out,test不會(huì)輸出,goto跳轉(zhuǎn)
__Require_Quiet(msg != nil, _out);
NSLog(@"test");
_out:
NSLog(@"out");
//__Require_Quiet 到_out之間的代碼不會(huì)執(zhí)行
2.4 獲取本地文件屬性
獲取本地文件屬性
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[fileURL path] error:error]
2.5 根據(jù)文件后綴獲取文件類型(同一類型標(biāo)識(shí)符)
#import <MobileCoreServices/MobileCoreServices.h>
static inline NSString * AFContentTypeForPathExtension(NSString *extension) {
NSString *UTI = (__bridge_transfer NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)extension, NULL);
NSString *contentType = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)UTI, kUTTagClassMIMEType);
if (!contentType) {
return @"application/octet-stream";
} else {
return contentType;
}
}
2.6 簡(jiǎn)單動(dòng)態(tài)圖片
UIImage *image0 = [UIImage imageNamed:@"SenderVoiceNodePlaying001"];
UIImage *image1 = [UIImage imageNamed:@"SenderVoiceNodePlaying002"];
UIImage *image2 = [UIImage imageNamed:@"SenderVoiceNodePlaying003"];
self.imageView.image = [UIImage animatedImageWithImages:@[image0,image1,image2] duration:1.5];