天天看点

iOS开发实用技术之换肤和静态库

一 换肤

  • 基本的换肤功能实现
  • 选中皮肤保存至系统偏好
// 记录用户选中的皮肤
  [[NSUserDefaults standardUserDefaults] setObject:skinColor forKey:@"skinColor"];
  [[NSUserDefaults standardUserDefaults] synchronize];
           
  • 抽取SkinTools单例,简化视图控制器的皮肤管理工作
    • 多控制器换肤
+ (UIImage *)skinToolWithImageName:(NSString *)imageName
 {
    NSString *imageNamePath = [NSString stringWithFormat:@"skin/%@/%@", _skinColor, imageName];

    return [UIImage imageNamed:imageNamePath];
 }
           
+ (void)setSkinColor:(NSString *)skinColor
 {
    _skinColor = skinColor;
    // 记录用户选中的皮肤
    [[NSUserDefaults standardUserDefaults] setObject:skinColor forKey:@"skinColor"];
    [[NSUserDefaults standardUserDefaults] synchronize];
 }
           
  • 添加TabBar演练皮肤切换
+ (UIColor *)skinToolWithLabelBgColor
{
    // 1.找到对应背景的plist文件
    NSString *bgColorFileName = [NSString stringWithFormat:@"skin/%@/BgColor.plist", _skinColor];
    NSString *bgColorFilePath = [[NSBundle mainBundle] pathForResource:bgColorFileName ofType:nil];

    // 2.加载背景颜色
    // 2.1.加载背景字典
    NSDictionary *bgColorDict = [NSDictionary dictionaryWithContentsOfFile:bgColorFilePath];

    // 2.2.取出背景颜色的字符串
    NSString *bgColorString = bgColorDict[@"LabelBgColor"];

    // 2.3.取出背景颜色的数组(0,255,0)
    NSArray *bgColorArray = [bgColorString componentsSeparatedByString:@","];

    // 2.4.取出对应的RGB值
    NSInteger red = [bgColorArray[] integerValue];
    NSInteger green = [bgColorArray[] integerValue];
    NSInteger blue = [bgColorArray[] integerValue];

    return [UIColor colorWithRed:red /  green:green /  blue:blue /  alpha:];
}
           
/**
 *  当类第一次使用的时候会调用该方法,该方法只会调用一次
 */
 + (void)initialize
 {
    // 1.先从偏好设置中取出用户之前选中的皮肤
    _skinColor = [[NSUserDefaults standardUserDefaults] objectForKey:@"skinColor"];

    // 2.判断skinColor是否为空,如果为空,表示用户之前没有选中皮肤,那么显示蓝色皮肤
    if (_skinColor == nil) {
        _skinColor = @"blue";
    }
 }
           

二 静态库

1.介绍静态库

  • 什么是库?
    • 库是程序代码的集合,是共享程序代码的一种方式
  • 根据源代码的公开情况,库可以分为2种类型
    • 开源库
    • 闭源库
      • 静态库
      • 动态库
  • 静态库和动态库的存在形式:
    • 静态库:.a 和 .framework
    • 动态库:.dylib 和 .framework
  • 静态库和动态库在使用上的区别
    • 静态库:链接时,静态库会被完整地复制到可执行文件中,被多次使用就有多份冗余拷贝
    • 动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存
需要注意的是:项目中如果使用了自制的动态库,不能被上传到AppStore

2.制作.a的静态库(Framework&Library)

  • 包含头⽂文件(项⺫⽬目—>build Phase—>copy File—>选中头⽂文件)
    iOS开发实用技术之换肤和静态库
  • 创建项⺫⽬目测试静态库
  • 设备CPU架构—>lipo -info lipo -create 静态库12 -output 静态库

每一个手机都有属于自己的CPU,而每一个CPU都有属于自己的CPU架构(指令集)

每一个静态库都有自己可以支持的架构:

  • 手机和模拟器使用的CPU架构
    • 模拟器CPU架构:
      • iPhone4s–>iphone5 : i386
      • iphone5s–>iphone6s plus : x86_64
    • 真机CPU架构
      • iPhone3gs–>iphone4s : armv7
      • iphone5–>iphone5c : armv7s(如果一个静态库支持armv7架构,也可以跑在架构是armv7s的设备,没有对代码进行优化)
      • iPhone5s–>iPhone6s plus : arm64
    • 查看静态库支持的架构:lipo -info 静态库名称
    • 合并静态库:lipo -create 静态库1 静态库2 -output 新的静态库
    • 编译静态库支持所有模拟器CPU架构设置
      iOS开发实用技术之换肤和静态库

3.边开发边制作静态库

- 添加一个静态库的targets—>点击项⺫⽬目—>targets—>+

iOS开发实用技术之换肤和静态库
  • 测试静态库: 项⺫⽬目—>项⺫⽬目的target—>general—>linked framework—>添加静态库
    iOS开发实用技术之换肤和静态库
  • 打包静态库—>选中项⺫⽬目静态库—>编译(头⽂文件)
    iOS开发实用技术之换肤和静态库

4.使⽤用静态库的注意点:

  • 静态库有真机和模拟器(测试阶段可以使⽤模拟器,发布阶段使⽤真机)。好处:资源包变⼩
  • 静态库有Debug版和release版本(测试阶段使⽤用Debug,发布阶段使⽤release)。好处:资源包变⼩/运⾏速度变快/代码进⾏优化
    • 调试版本会包含完整的符号信息,以方便调试
    • 调试版本不会对代码进行优化
    • 发布版本不会包含完整的符号信息
    • 发布版本的执行代码是进行过优化的
    • 发布版本的大小会比调试版本的略小
    • 在执行速度方面,发布版本会更快些,但不意味着会有显著的提升
  • 编译Debug版或release版本静态库设置
    • StaticLib→Edit Scheme→截图
      iOS开发实用技术之换肤和静态库
    5.制作.framework库
    • 1>动态库(默认)

      注意:如果项⺫中⽤到了动态库进⾏设置:项⺫—>项⺫的target—> general— >Embedded—>添加动态库

      iOS开发实用技术之换肤和静态库
    • 2>静态库

      制作静态库的修改配置:项⺫—>静态库的target—>build setting—>搜索mach —>static library

      iOS开发实用技术之换肤和静态库
    • 3>注意点

      查看一个.framework静态库⽀持哪些架构:lipo -info framework⽂件下⾯的⼆进制

      合并静态库:合并framework⽂件下⾯的⼆进制

三 支付宝集成

  1. 向支付宝申请, 与支付宝签约,获得商户ID(partner)和账号ID(seller)和私钥(privateKey)
  2. 下载支付宝SDK
  3. 生成订单信息,签名加密
  4. 调用支付宝客户端,由支付宝客户端跟支付宝安全服务器打交道
  5. 支付完毕后,支付宝客户端会自动跳回到原来的应用程序
  6. 在原来的应用程序中显示支付结果给用户看
    • 如果用户没有安装支付宝客户端,直接在应用程序中添加一个WebView,通过网页让用户进行支付
// 注意:如果是通过网页支付完成,那么会回调该block:callback
    [[AlipaySDK defaultService] payOrder:orderString fromScheme:@"jingdong" callback:^(NSDictionary *resultDic) {

    }];
}
           
  • 通过支付宝
// 当通过别的应用程序,将该应用程序打开时,会调用该方法
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options
{
    // 当用户通过支付宝客户端进行支付时,会回调该block:standbyCallback
    [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
        NSLog(@"result = %@",resultDic);
    }];  
    return YES;
}
           
  • 注意报错:找不到路径时添加路径
    iOS开发实用技术之换肤和静态库

四 内存分析

  • 1.静态内存分析
    • 不运⾏程序,直接对代码进⾏内存分析,查看代码是否有内存泄露
    • 优点:分析速度快,并且可以对所有的代码进⾏内存
    • 缺点:分析不一定准确(没有运⾏程序,根据代码的上下文语法结构)
    • 注意:如果有提⽰有内存泄露,⼀定结合代码查看代码是否有问题.
  • 2.动态内存分析(会使⽤Instruments对APP进⾏行内存分析)
    • 真正运⾏起来程序,对程序进⾏内存分析(查看内存分配情况/内存泄露)
    • 优点:分析⾮常准确,如果发现有提⽰内存泄露.基本可以断定代码问题
    • 缺点:分析效率低(真正运⾏了⼀段代码,才能对该代码进⾏内存分析)
    • 注意:如果发现有内存泄露,基本需要修改代码(基本有内存泄露)
    • 使⽤Instruments:Product→Profile→打开Instruments工具
    • Allocations:内存分配
    • Leaks: 内存泄露
  • 2种加载图片方法对比:
    • imageName:
      • 1.加载的图片不会随着对象的销毁
      • 2.如果多个UIImage对象需要使用图片对象,图片对象只会存在一份
    • imageContentOfFile:
      • 1.加载的图片会随着对象的销毁一起销毁
      • 2.如果多个UIImage对象需要使用图片对象,那么就会存在多个图片对象