美文网首页
WWDC2017-- What's New in LLV

WWDC2017-- What's New in LLV

作者: 程序媛coco | 来源:发表于2017-08-15 00:30 被阅读71次

Objective - C 可用性检查

场景:
由于iOS系统每年都会有新的功能新的API发布,我们希望能够把这些新API在我们的App里使用,但是你仍然要支持旧的系统,你不可能要求安装你App的用户的手机系统都是最新的,这些新的API在旧系统中无法使用;
但是在iOS系统里支持反向配置,可以设置build setting最低支持版本;
但是这样并不安全,如果你在iOS9的设备上调用了iOS11的方法,你的App就很有可能会Crash或出现其他意外情况;
下面就来说可用性检查怎么帮助用户安全配置App到旧的系统中?

以前的做法:
  • 查询OC运行时,来确定API是否适用,但是这样很容易出错或者忘记判断直接执行,如果出错很难测试定位问题,而且它需要不同的语法来检查每项全局变量、函数、类、实例方法和类方法;
  • 在Swift 2.0 已经支持使用语法关键字#available,在运行时查询API的可用性;编译器在编译时能捕捉缺失的可用性,相关的可以具体到WWDC 2015 <Swift in Practice>
现在的做法:
  • 在iOS11中把Swift的可用性检查引入到Objective - C
  • 如果直接调用新的API,编译器会报如下警告:
image.png
  • 使用@available查询API可用性,来处理警告
image.png
注:当当前是iOS11,@available结构返回值为真,这种情况下调用API很安全,如果当前系统不适合,则可以在else函数处理
  • if (@available(iOS 11, *)) 在iOS11或者更新的系统里返回真,* 号表明在其它所有平台上查询为真(比如macOS)
  • 可用性针对新系统定制的一套功能很方便

应用指定方法:在方法实现里无需再加@available检查可用性,但调用该方法的人需要使用,否则会收到警告

@interface MyAlbumController : UIViewController
- (void)showFaces API_AVAILABLE(ios(11.0)); 
@end

应用到指定类:

API_AVAILABLE(ios(11.0))
@interface MyAlbumController : UIViewController
- (void)showFaces; 
@end
C/C++的用性检查API
  • __builtin_available
if (__builtin_available(iOS 11, macOS 10.13, *)) { 
    CFNewAPIOniOS11();
}
  • API_AVAILABLE宏需要包含<os/availability.h>
#include <os/availability.h>
// 修饰方法
void myFunctionForiOS11OrNewer(int i) API_AVAILABLE(ios(11.0), macos(10.13));

// 修饰类
class API_AVAILABLE(ios(11.0), macos(10.13)) MyClassForiOS11OrNewer;

建议:对于现有项目,不建议直接使用新的API,需要使用@available或者API_AVAILABLE检查新API的可用性


对于查找定位bug,以下介绍一些Xcode的新功能,如静态分析新功能和编译器警告~

Analyzer 静态分析新功能

Analyzer擅长捕捉难以重现的极端的bug,下面介绍新加入Analyzer的三种情况:

对于 NSNumberCFNumberRef的一些错误比较方式
  • 错误一:NSNumber指针值直接和0比,这个操作实际上是将指针值和nil相比较
@property NSNumber *photoCount; 
- (BOOL)hasPhotos {
    return self.photoCount > 0;  // X 错误:不能用NSNumber直接和0比较
}
image.png
@property NSNumber *photoCount;
- (BOOL)hasPhotos {
return self.photoCount.integerValue > 0; // 正确: compare integer value to integer value
}
  • 错误二:布尔运算的隐式变换的歧义
@property NSNumber *faceCount;
- (void)identifyFaces { 
  if (self.faceCount)  // 歧义:这里`faceCount`是为nil还是0的时候return?
    return;
    // Expensive Processing
}
image.png

明确的和nil做比较!

@property NSNumber *faceCount;
- (void)identifyFaces {
    if (self.faceCount) != nil)
    return;
    // Expensive Processing
}

在Xcode设置检查选项:


image.png
函数 dispatch_once()的使用注意

这个函数它保证这个代码块会被调用一次并且只有一次,常用于初始化共享全局状态;
确保代码块只执行一次,第一个参数必须是global 或则 static的变量

image.png image.png

解决方案:使用NSLock 确保初始化只执行一次

@implementation Album { 
NSLock *photosLock;
}
[photosLock lock];
if (self.photos == nil) { 
  self.photos = [self loadPhotos];
}
[photosLock unlock];
关于NSMutable类的copy 属性的检查

定义一个可变类型的propertycopy修饰时,一般会在该属性的Setter方法里对属性进行 -copy操作,这样会导致该可变类型变成不可变类型

会有如下问题:

image.png

Analyzer 中的提示信息:


image.png

解决方案:在Setter方法明确的执行 -mutableCopy,确保属性是可变的

image.png

相关WWDC议题:Finding Bugs Using Xcode Runtime Tools

编译器警告

Xcode9新加了100多个错误和警告,来帮助我们调试和处理问题,下面有两个很重要的错误警告:

在ARC的Block里捕获参数:

一般来说,在ARC的Block里捕获大多数的参数都很安全

请找出下面代码会出问题的地方:

- (BOOL)validateDictionary:(NSDictionary *)dict usingChecker:(Checker *)checker error:(NSError **)error {
    __block BOOL isValid = YES;
    [dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
      if ([checker checkObject:obj forKey:key]) return; 
        *stop = YES;    
        isValid = NO;
      if (error) *error = [NSError errorWithDomain:...]; // 在 Block里分配参数是很不安全的
      // if (error) *error = [[[NSError errorWithDomain:...] retain] autorelease]; //默认会加上`__autoreleasing`
    }];
    return isValid; 
}

注意:

  1. 在 Block里分配参数是很不安全的,在ARC Block的外部参数会隐式的被加上__autoreleasing
  2. enumerateKeysAndObjectsUsingBlock这个block 内部默认有autoreleasepool

具体警告如下:


image.png

解决方案:使用__strong修饰输出参数,确保输出时对象存在,没有被销毁

image.png
声明没有参数的方法

在iOS9,需要明确指定无参为void, 不然会报如下警告:

image.png

明确设置函数的无参void 后,对该函数传递参数会直接报错:

image.png

在 Build Setting里配置:


image.png

(LTO:Link-Time Optimization)链接时间优化更新

相关WWDC 2016:What's New in LLVM


相关 Sessions

image.png

相关文章

  • WWDC2017-- What's New in LLV

    Objective - C 可用性检查 场景:由于iOS系统每年都会有新的功能新的API发布,我们希望能够把这些新...

  • What's new in Swift 4.0

    Hands-on code examples to help you learn what's new in Sw...

  • What's new in graphics and g

    本系列文章是对 http://metalkit.org 上面MetalKit内容的全面翻译和学习. MetalKi...

  • What's new in Xcode 9

    前言 WWDC过后, 苹果发布了一系列的Beta 版固件及工具,我们单表其一,看看Xcode 9中的新功能。如果你...

  • Swift 4.0 | What's new in it

    文 / 菲拉兔 要求: Platform: iOS8.0+ Language: Swift4.0 Editor: ...

  • What's new in Swift 3.1

    2017年3月27日,Apple官方发布了Swift 3.1。Swift 3.1 是一个小版本的更新,主要包含了包...

  • What's new in Xcode 8

    以下是苹果官方对Xcode 8新特性的描述,进行了一些翻译: Xcode 8 包含了你为iPhone、iPad、M...

  • What's New in iOS 11

    iOS 11.0 本文总结了iOS 11中推出的主要开发者相关功能,该功能在当前运行的iOS设备上运行。该文章还列...

  • What's New in Swift 3?

    备注:本文章是翻译,如果大家想看原文请点击链接,第一次翻译谢谢。 如果你还没有经常去GitHub上看Swift E...

  • 精读《What's new in javascript》

    1. 引言 本周精读的内容是:Google I/O 19。 2019 年 Google I/O 介绍了一些激动人心...

网友评论

      本文标题:WWDC2017-- What's New in LLV

      本文链接:https://www.haomeiwen.com/subject/djtgwttx.html