iOS開發經驗總結3

Xcode8更新了
項目時間緊張了,要本身帶孩子了,又有同事離職了,G20來了,寫做興致不高了。。。等等緣由,就是不想寫點什麼,就想躺在沙發上,什麼都不想動。今天2個版本終於提交App Store了,忽然有好多時間能夠揮霍,非常HAPPY。^-^

1、 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
複製代碼

2、 NSInteger打印以及字符串的轉換

使用%zd打印NSInteger, %tu打印NSUInteger。html

NSInteger integer = 1;
NSLog(@"first number: %zd", integer);

NSUInteger uinteger = 1;
NSLog(@"second number: %tu", uinteger);
複製代碼

3、 UIScrollView 在iOS7中使用了Autolayout 致使不能滾動

- (void)viewDidLayoutSubviews
{
     [_mainScrollView setContentSize:CGSizeMake(SCREEN_WIDTH, SCREEN_HEIGHT + 10)];//增長10個像素讓scrollview可上下滑動
}
複製代碼

添加scrollView的content高度.ios

4、 APP包瘦身

1. 刪除項目中沒有使用的圖片。 查找XCode工程中沒被使用的圖片資源
2. 刪除項目中沒有用到的class 和 xib 及storyboard。 分析工程中沒有用到class

安裝 fui 工具 sudo gem install fui -n /usr/local/bingit

fui usage: github.com/dblock/fuigithub

到工程目錄下,執行 fui find 命令,能夠找出全部的沒有用到的class文件。web

3. 分析ipa包,找出大於500K的文件或內容 使用
find . -type f -size +500000c | xargs ls -lh
複製代碼

圖形搜索法

5、 直接iOS7的連續跳轉

- (void)back
{
    [self dismissViewControllerAnimated:YES
                             completion:^{
                                 if (self.loginCanceled) {
                                     self.loginCanceled();
                                     
                                     self.loginCanceled = nil;
                                 }
                             }];
}
複製代碼

其中loginCanceled的實現數據庫

[weakSelf.navigationController popViewControllerAnimated:YES];數組

6、 去除Preferred Max 的警告

警告的緣由:xcode

  1. xib或storyboard中添加了UILabel的控件
  2. UILabel的number lines 大於1
  3. UILabel的preferred max沒有設置值( @property(nonatomic) CGFloat preferredMaxLayoutWidth NS_AVAILABLE_IOS(6_0);)

解決方法:緩存

  1. 若是是Storyboard的,右鍵點擊警告
    警告
  2. 查看警告的詳情

詳情
3. 複製ID的值在搜索框中進行搜索

搜索
4. 點擊搜索到的Label,能夠找到label

找到Label

  1. 設置preferred width爲0,並選中explicit
    設置
  2. 警告解決

若是警告的是Xib,直接點擊警告 bash

xib
就會跳轉到對應的UILabel控件,設置preferred width爲0,並選中explicit。 警告解決。

7、 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的安裝

8、 interactivepopgesturerecognizer 使用

設置left bar button後,會致使右滑返回的效果失效,查看完美的設置方案。

同時爲了獲取到右滑返回的事件,能夠執行 [self.navigationController.interactivePopGestureRecognizer addTarget:self action:@selector(back)];

**在ViewController中viewDidAppare中添加,在viewWillDisappear中remove。 **

9、 更新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

10、 UICollectionView的數據不夠,沒法滑動——解決方案

tableView的數據不管多少,它的界面默認都是能夠滑動的。 和tableView相比,當collectionView的數據較少不夠一個屏幕時,它沒法滑動。 解決方案:

_collectionView.alwaysBounceVertical = YES;
複製代碼

設置爲總能垂直滑動就OK了。

11、 MLeaksFinder 檢查內存泄露

MLeaksFinder  直接用Pod導入就能夠。根據DEBUG這個宏,開啓內存泄露的檢查,若是發現內存泄露,將斷言。 So Good

12、 刪除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;
}
複製代碼

十3、 iOS8 之後用WKWebView替代UIWebView

iOS8 以前使用UIWebView進行html的展現,使用UIWebView存在內存佔用過大並不釋放的問題。

WKWebView解決了內存佔用過大的問題。

十4、 Xib中UILabel換行

在Xib中輸入很長的文字,須要根據編號進行換行時,按「Enter」鍵無效。

方法:將文字在Text編輯工具編寫好,copy到UILabel上。換行就有了

十5、 workspace — project — targets 講解

一個工做空間能夠包含多個項目,一個項目能夠包含多個目標(生成物)。

一個項目中根據運行的targets不一樣,能夠進行不一樣的編譯設置,project是基礎父類,targets是子類,targets的設置會覆蓋project的設置。

十6、 繪畫虛線,  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方法中,進行繪畫。

十7、 Array 的深複製

指針的複製 dataArray3=[dataArray2 mutableCopy]; 知識對dataArray2 進行了深複製,數組中的內容僅僅是指針的複製。

單層深複製 dataArray3=[[NSMutableArray alloc]initWithArray:dataArray2 copyItems:YES]; dataArray2進行自己和內容的深複製。單僅僅是內容的第一層

徹底深複製 dataArray3 = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:dataArray2]]; 無論多少層均可以進行了深複製

十8、 企業證書下載版本可在APP中直接打開

在APP中有H5的頁面,能夠直接點擊進行其餘應用的下載

十9、 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);
複製代碼

輸出:   test.fd.com/#/dte{}|||?…

# 沒有被轉義 **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{}|||.

二10、 APP 啓動頁不更新

修改了LaunchScreen.xib 後,模擬器上顯示正常,可是真機上沒有更新。

緣由: 應用緩存

解決:

真機上刪除APP,重啓手機,從新安裝APP。

二11、 httpsdns 使用

申請 account id  下載sdk

查看SDK 文檔 初始化,替換域名爲IP

help.aliyun.com/document_de…

在阿里雲 裏配置域名

二12、 打印不出變量的值 都顯示nil

當對某個變量進行調試的並打印值時,一直返回nil。可是界面又能顯示內容。

緣由:

說明這個變量是在某個線程中,而調試的不在這個線程裏。

二十3、 判斷是否爲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);
複製代碼

二十4、 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;
},
});
複製代碼

二十5、 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以前來解決。

二十6、 xcode8 出現ubsystem: com.apple.UIKit, category: HIDEventFiltered。。。的日誌

解決辦法:【product】-【scheme】-【Edit Scheme】-【Run】-【Argument】-【Environment Variable】添加keyValue【OS_ACTIVITY_MODE   disable】能夠中止輸出打印此日誌

二十7、 intrinsic size 同一行有2個可變長度的的UILabel

Content Hugging Priority表明控件拒絕拉伸的優先級。優先級越高,控件會越不容易被拉伸。

而下面的Content Compression Resistance Priority表明控件拒絕壓縮內置空間的優先級。優先級越高,控件的內置空間會越不容易被壓縮

設置Content Hugging Priority 和 Content Compression Resistance Priority, 可實現當2個UILabel的內容都很長的時候,哪一個label進行壓縮,哪一個Label進行顯示完整。

二十8、 pusher 推送測試

github.com/noodlewerk/…

直接進行推送的測試。 👍👍👍

二十9、 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;
}
複製代碼

三10、 個推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中就不會出現顯示代碼了

三11、 iOS10 默認的frame

<UIImageView: 0x7f9b91560f50; frame = (0 0; 1000 1000); clipsToBounds = YES; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x6000000366e0>

三12、 騰訊手機管家 騷擾攔截 數據庫更新失敗

騷擾攔截功能,進行數據庫更新時,若是是英文環境,一直會出現數據庫更新失敗,切換到中文環境,一次性就成功了。

// TODO 發現知識點過期真的好快啊!

相關文章
相關標籤/搜索