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 发现知识点过期真的好快啊!

相关文章
相关标签/搜索