一、 cocoa pods 常用的framework
platform :ios, '7.0'
target 'store' do
pod 'AFNetworking', '~> 3.1.0'
pod 'JSONKit', '~> 1.5pre'
pod 'MBProgressHUD', '~> 0.9.2'
pod 'SDWebImage', '~> 3.7.6'
pod 'SVPullToRefresh', '~> 0.4.1'
pod 'JTObjectMapping', '~> 1.1.2'
pod 'MagicalRecord', '~> 2.3.2'
pod 'GetuiSDK', '~> 1.4.2'
pod 'XTSafeCollection', '~> 1.0.4'
pod 'libWeChatSDK', '~> 1.6.2'
pod 'XMLDictionary', '~> 1.4'
pod 'Masonry', '~> 1.0.0'
pod 'OpenUDID', '~> 1.0.0'
pod 'SAMKeychain', '~> 1.5.0'
pod 'iVersion', '~> 1.11.4'
pod 'iCloudDocumentSync', '~> 7.4.1'
end
複製程式碼
二、 NSInteger列印以及字串的轉換
使用%zd列印NSInteger, %tu列印NSUInteger。
NSInteger integer = 1;
NSLog(@"first number: %zd", integer);
NSUInteger uinteger = 1;
NSLog(@"second number: %tu", uinteger);
複製程式碼
三、 UIScrollView 在iOS7中使用了Autolayout 導致不能滾動
- (void)viewDidLayoutSubviews
{
[_mainScrollView setContentSize:CGSizeMake(SCREEN_WIDTH, SCREEN_HEIGHT + 10)];//增加10個畫素讓scrollview可上下滑動
}
複製程式碼
新增scrollView的content高度.
四、 APP包瘦身
1. 刪除專案中沒有使用的圖片。 查詢XCode工程中沒被使用的圖片資源
2. 刪除專案中沒有用到的class 和 xib 及storyboard。 分析工程中沒有用到class
安裝 fui 工具 sudo gem install fui -n /usr/local/bin
fui usage: github.com/dblock/fui
到工程目錄下,執行 fui find 命令,可以找出所有的沒有用到的class檔案。
3. 分析ipa包,找出大於500K的檔案或內容 使用
find . -type f -size +500000c | xargs ls -lh
複製程式碼
五、 直接iOS7的連續跳轉
- (void)back
{
[self dismissViewControllerAnimated:YES
completion:^{
if (self.loginCanceled) {
self.loginCanceled();
self.loginCanceled = nil;
}
}];
}
複製程式碼
其中loginCanceled的實現
[weakSelf.navigationController popViewControllerAnimated:YES];
六、 去除Preferred Max 的警告
警告的原因:
- xib或storyboard中新增了UILabel的控制元件
- UILabel的number lines 大於1
- UILabel的preferred max沒有設定值(
@property(nonatomic) CGFloat preferredMaxLayoutWidth NS_AVAILABLE_IOS(6_0);
)
解決方法:
- 如果是Storyboard的,右鍵點選警告
- 檢視警告的詳情
- 設定preferred width為0,並選中explicit
- 警告解決
如果警告的是Xib,直接點選警告
就會跳轉到對應的UILabel控制元件,設定preferred width為0,並選中explicit。 警告解決。七、 Cocoa pods更新到1.0 不能用了
更新完cocoa pods後,執行pod install後提示 Errno::ENOTEMPTY - Directory not empty @ dir_s_rmdir - /Users/arthurwang/SVN///*/Pods
[!] Oh no, an error occurred.Search for existing GitHub issues similar to yours:github.com/CocoaPods/C… none exists, create a ticket, with the template displayed above, on:github.com/CocoaPods/C… sure to first read the contributing guide for details on how to properly submit a ticket:github.com/CocoaPods/C… Don't forget to anonymize any private data!
解決方法:
刪除專案中的Pods資料夾,再進行pod install的安裝
八、 interactivepopgesturerecognizer 使用
設定left bar button後,會導致右滑返回的效果失效,檢視完美的設定方案。
同時為了獲取到右滑返回的事件,可以執行
[self.navigationController.interactivePopGestureRecognizer addTarget:self action:@selector(back)];
**在ViewController中viewDidAppare中新增,在viewWillDisappear中remove。 **
九、 更新Cocoapods上的程式碼
1. 採用私有的Cocoapods管理程式碼,需要新增
pod repo add HXSpec git@code.59store.com:ios/HXSpecs.git
將私有的Spec管理Git新增到pod的specs中。為了方便更新私有庫。
2. 在使用Cocoapods管理程式碼的時候,如果在GitHut上更新了程式碼,希望在project中執行pod install 來重新整理程式碼,那麼需要刪除Pods和Podfile.lock檔案
然後在執行pod install 來重新整理程式碼
使用pod update進行repo的更新(更新私有庫)
3. 多次安裝pod install 會出現Build Phase裡多個Check Pods Manifest.lock的選項,這些選項可以刪除。
採用直接將specs檔案放到HXSpecs的管理庫中,那麼需要執行pod update 進行 Updating local specs repositories 不然會報錯
4. 刪除這個目錄下的快取檔案,進行第三方庫檔案的重新獲取
/Users/arthurwang/Library/Caches/CocoaPods/Pods
5. 進行兩個元件相互依賴的時候,會導致報錯:
[!] There is a circular dependency between StoreLocation and StoreBase
十、 UICollectionView的資料不夠,無法滑動——解決方案
tableView的資料無論多少,它的介面預設都是可以滑動的。 和tableView相比,當collectionView的資料較少不夠一個螢幕時,它無法滑動。 解決方案:
_collectionView.alwaysBounceVertical = YES;
複製程式碼
設定為總能垂直滑動就OK了。
十一、 MLeaksFinder 檢查記憶體洩露
MLeaksFinder 直接用Pod匯入就可以。根據DEBUG這個巨集,開啟記憶體洩露的檢查,如果發現記憶體洩露,將斷言。 So Good
十二、 刪除String的中文
思路: 採用刪除不用需要保留的字元,來實現刪除中文的目的
//數字和字母
#define ALPHANUM @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
//數字
#define NUM @"0123456789"
NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:ALPHANUM] invertedSet];
NSString *filteredStr = [[textStr componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
複製程式碼
另外:UITextField 只能輸入數字和字母
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(textFieldChanged:)
name:UITextFieldTextDidChangeNotification
object:nil];
複製程式碼
監聽name:UITextFieldTextDidChangeNotification
和 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
一起使用,來實現。
- (BOOL)validatePasswordString:(NSString *)resultMStr
{
BOOL result = YES;
switch (self.mode) {
case HXSChangePasswordLogin: {
NSString *regex = @"^[a-zA-Z0-9]+$";
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
result = [pred evaluateWithObject:resultMStr];
break;
}
case HXSChangePasswordPay: {
NSString *regex = @"^[0-9]+$";
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
result = [pred evaluateWithObject:resultMStr];
break;
}
}
return result;
}
複製程式碼
十三、 iOS8 以後用WKWebView替代UIWebView
iOS8 之前使用UIWebView進行html的展示,使用UIWebView存在記憶體佔用過大並不釋放的問題。
WKWebView解決了記憶體佔用過大的問題。
十四、 Xib中UILabel換行
在Xib中輸入很長的文字,需要根據編號進行換行時,按“Enter”鍵無效。
方法:將文字在Text編輯工具編寫好,copy到UILabel上。換行就有了
十五、 workspace — project — targets 講解
一個工作空間可以包含多個專案,一個專案可以包含多個目標(生成物)。
一個專案中根據執行的targets不同,可以進行不同的編譯設定,project是基礎父類,targets是子類,targets的設定會覆蓋project的設定。
十六、 繪畫虛線, drawRect繪畫frame未定的情況
[yourView.layer setBorderWidth:5.0];
[yourView.layer setBorderColor:
[[UIColor colorWithPatternImage:[UIImage imageNamed:@"DotedImage.png"]] CGColor]];//just add image name and create image with dashed or doted drawing and add here
複製程式碼
這裡只需要新增QuartzCore/QuartzCore.h框架,像下面一樣匯入.m檔案:
#import <QuartzCore/QuartzCore.h>
複製程式碼
注意: 當使用Autolayout後,繪畫虛線是根據frame進行的,那麼在
- (void)drawRect:(CGRect)rect
{
[self drawBorderLayer];
}
複製程式碼
drawRect方法中,進行繪畫。
十七、 Array 的深複製
指標的複製
dataArray3=[dataArray2 mutableCopy];
知識對dataArray2 進行了深複製,陣列中的內容僅僅是指標的複製。
單層深複製
dataArray3=[[NSMutableArray alloc]initWithArray:dataArray2 copyItems:YES];
dataArray2進行本身和內容的深複製。單僅僅是內容的第一層
完全深複製
dataArray3 = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:dataArray2]];
不管多少層都可以進行了深複製
十八、 企業證書下載版本可在APP中直接開啟
在APP中有H5的頁面,可以直接點選進行其他應用的下載
十九、 URL中對“#”的處理
NSString *str = @"http://test.fd.com/#/dte{}|||?lsfj=12&sdlfj=34&hao=你好";
NSURL *url = [NSURL URLWithString:[str stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet characterSetWithCharactersInString:@"`%^{}\"[]|\\<> "].invertedSet]];
NSLog(@"url is %@", url);
複製程式碼
# 沒有被轉義
**iOS9版本中需要使用 **
stringByAddingPercentEncodingWithAllowedCharacters
替代之前
stringByAddingPercentEscapesUsingEncoding
。
NSString *str = @"http://test.fd.com/#/dte{}|||?lsfj=12&sdlfj=34&hao=你好";
NSURL *url = [NSURL URLWithString:[str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSLog(@"[url scheme] is %@.", [url scheme]);
NSLog(@"[url host] is %@.", [url host]);
NSLog(@"[url password] is %@.", [url password]);
NSLog(@"[url user] is %@.", [url user]);
NSLog(@"[url path] is %@.", [url path]);
NSLog(@"[url query] is %@.", [url query]);
NSLog(@"[url fragment] is %@.", [url fragment]);
NSLog(@"[url resourceSpecifier] is %@.", [url resourceSpecifier]);
NSLog(@"[url parameterString] is %@.", [url parameterString]);
NSLog(@"[url relativePath] is %@.", [url relativePath]);
複製程式碼
輸出: 2016-08-09 18:57:52.913 store[20150:672790] [url scheme] is http. 2016-08-09 18:57:52.913 store[20150:672790] [url host] is test.fd.com. 2016-08-09 18:57:52.914 store[20150:672790] [url password] is (null). 2016-08-09 18:57:52.914 store[20150:672790] [url user] is (null). 2016-08-09 18:57:52.914 store[20150:672790] [url path] is /#/dte{}|||. 2016-08-09 18:57:52.914 store[20150:672790] [url query] is lsfj=12&sdlfj=34&hao=%E4%BD%A0%E5%A5%BD. 2016-08-09 18:57:52.914 store[20150:672790] [url fragment] is (null). 2016-08-09 18:57:52.915 store[20150:672790] [url resourceSpecifier] is //test.fd.com/%23/dte{}|||?lsfj=12&sdlfj=34&hao=你好. 2016-08-09 18:57:52.915 store[20150:672790] [url parameterString] is (null). 2016-08-09 18:57:52.915 store[20150:672790] [url relativePath] is /#/dte{}|||.
二十、 APP 啟動頁不更新
修改了LaunchScreen.xib 後,模擬器上顯示正常,但是真機上沒有更新。
原因: 應用快取
解決:
真機上刪除APP,重啟手機,重新安裝APP。
二十一、 httpsdns 使用
申請 account id 下載sdk
檢視SDK 文件 初始化,替換域名為IP
在阿里雲 裡配置域名
二十二、 列印不出變數的值 都顯示nil
當對某個變數進行除錯的並列印值時,一直返回nil。但是介面又能顯示內容。
原因:
說明這個變數是在某個執行緒中,而除錯的不在這個執行緒裡。
二十三、 判斷是否為gif/png圖片的正確姿勢
//通過圖片Data資料第一個位元組 來獲取圖片副檔名
- (NSString *)contentTypeForImageData:(NSData *)data
{
uint8_t c;
[data getBytes:&c length:1];
switch (c)
{
case 0xFF:
return @"jpeg";
case 0x89:
return @"png";
case 0x47:
return @"gif";
case 0x49:
case 0x4D:
return @"tiff";
case 0x52:
if ([data length] < 12) {
return nil;
}
NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding];
if ([testString hasPrefix:@"RIFF"]
&& [testString hasSuffix:@"WEBP"])
{
return @"webp";
}
return nil;
}
return nil;
}
複製程式碼
其實圖片資料的第一個位元組是固定的,一種型別的圖片第一個位元組就是它的標識, 我們來呼叫一下這個方法:
//假設這是一個網路獲取的URL
NSString *path = @"http://pic.rpgsky.net/images/2016/07/26/3508cde5f0d29243c7d2ecbd6b9a30f1.png";
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:path]];
//呼叫獲取圖片副檔名
NSString *string = [self contentTypeForImageData:data];
//輸出結果為 png
NSLog(@"%@",string);
複製程式碼
二十四、 JSPatch 的convertor 工具使用
左邊輸入
@implementation HXSAdTableViewCell
+ (CGFloat)getCellHeightWithObject:(HXSStoreAppEntryEntity *)storeAppEntryEntity
{
CGFloat scale = [storeAppEntryEntity.imageHeightIntNum floatValue]/[storeAppEntryEntity.imageWidthIntNum floatValue];
return ([UIScreen mainScreen].bounds.size.width) / 3 * scale + 30;
}
@end
複製程式碼
右邊輸出
require('UIScreen');
defineClass('HXSAdTableViewCell', {} {
getCellHeightWithObject: function(storeAppEntryEntity) {
var scale = storeAppEntryEntity.imageHeightIntNum().floatValue() / storeAppEntryEntity.imageWidthIntNum().floatValue();
return (UIScreen.mainScreen().bounds().size().width()) / 3 * scale + 30;
},
});
複製程式碼
有一個BUG: ** defineClass('HXSAdTableViewCell', {} {** 在{}後面少一個**“,”**。
正確:
require('UIScreen');
defineClass('HXSAdTableViewCell', {}, {
getCellHeightWithObject: function(storeAppEntryEntity) {
var scale = storeAppEntryEntity.imageHeightIntNum() / storeAppEntryEntity.imageWidthIntNum();
return (UIScreen.mainScreen().bounds().width) / 3 * scale + 30;
},
});
複製程式碼
二十五、 Navigation bar的left bar button 跳動
- (void)jumpToViewController:(UIViewController *)vc
{
// show the navigation bar in other vcs
[self.navigationController setNavigationBarHidden:NO];
[self.navigationController pushViewController:vc animated:YES];
}
複製程式碼
當設定了 self.navigationItem.leftBarButtonItem.imageInsets = self.navigationController.viewControllers.count == 1 ? UIEdgeInsetsZero : UIEdgeInsetsMake(0, -5, 0, 5);
那麼進行顯示navigation bar的時候,就引起left bar button的跳動。
可以設定navigation bar hidden在push之前來解決。
二十六、 xcode8 出現ubsystem: com.apple.UIKit, category: HIDEventFiltered。。。的日誌
解決辦法:【product】-【scheme】-【Edit Scheme】-【Run】-【Argument】-【Environment Variable】新增keyValue【OS_ACTIVITY_MODE disable】可以停止輸出列印此日誌
二十七、 intrinsic size 同一行有2個可變長度的的UILabel
Content Hugging Priority代表控制元件拒絕拉伸的優先順序。優先順序越高,控制元件會越不容易被拉伸。
而下面的Content Compression Resistance Priority代表控制元件拒絕壓縮內建空間的優先順序。優先順序越高,控制元件的內建空間會越不容易被壓縮
設定Content Hugging Priority 和 Content Compression Resistance Priority, 可實現當2個UILabel的內容都很長的時候,哪個label進行壓縮,哪個Label進行顯示完整。
二十八、 pusher 推送測試
直接進行推送的測試。 ???
二十九、 float的精度解決
將NSNumber轉化為CGFloat時,精度失真。
NSString *decimalNumberMutiplyWithString(NSString *multiplierValue,NSString *multiplicandValue)
{
NSDecimalNumber *multiplierNumber = [NSDecimalNumber decimalNumberWithString:multiplierValue];
NSDecimalNumber *multiplicandNumber = [NSDecimalNumber decimalNumberWithString:multiplicandValue];
NSDecimalNumber *product = [multiplicandNumber decimalNumberByMultiplyingBy:multiplierNumber];
return [product stringValue];
}
NSLog(@"%@",decimalNumberMutiplyWithString([NSString stringWithFormat:@"%f",a], [NSString stringWithFormat:@"%d",b])); //輸出結果 999999.99
複製程式碼
通過計算每一位的數字,再進行string展示。
- (NSString *)convertStringFromFloatNum:(NSNumber *)floatNum
{
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setPositiveFormat:@"0.00"];
NSString *tempFloatStr = [numberFormatter stringFromNumber:[NSNumber numberWithDouble:([floatNum floatValue] * 100)]]; // yuan to fen
NSInteger tempInt = [tempFloatStr integerValue];
NSInteger result = tempInt % 100;
if (0 == result) {
NSString *str = [NSString stringWithFormat:@"%zd", tempInt/100];
return str;
}
result = tempInt % 10;
if (0 == result) {
NSString *str = [NSString stringWithFormat:@"%zd.%zd", tempInt/100, (tempInt % 100)/10];
return str;
}
NSString *str = [NSString stringWithFormat:@"%zd.%zd%zd", tempInt/100, (tempInt % 100)/10, (tempInt % 100)%10];
return str;
}
複製程式碼
三十、 個推iOS10改動
iOS 10 中 “loc-key”和“body”(我們官網就是“message”)這二個欄位的優先順序發生了變化,在iOS 10中“body”的優先順序大於“loc-key”,在iOS 10以下“loc-key”大於“body”,不推薦使用“body”傳遞資料
將Message(對應body)中的資料放到payload中,將loc-key的資料放到message(對應body)中,在iOS 10中就不會出現顯示程式碼了
三十一、 iOS10 預設的frame
<UIImageView: 0x7f9b91560f50; frame = (0 0; 1000 1000); clipsToBounds = YES; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x6000000366e0>
三十二、 騰訊手機管家 騷擾攔截 資料庫更新失敗
騷擾攔截功能,進行資料庫更新時,如果是英文環境,一直會出現資料庫更新失敗,切換到中文環境,一次性就成功了。
// TODO 發現知識點過時真的好快啊!