返回

Xcode预编译开关宏命令简化去除警告及优化代码结构思路

IOS

Swift 语言跟 OC 语言的代码相互转换,特别是直接读取 OC 代码,在 Xcode 会报很多警告,其中 Pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified) 警告可能是比较多的。

如果不修改代码,可以试一下下面方法:

  1. 命令行打开项目目录:
open <#path of workspace#>
  1. 打开命令工具,执行下面命令:
xcrun swiftc -emit-library -O -module-name <#projectName#> -I $(find. -name *.h) -I $(find. -name *.pch) -I $(find. -name *.m) -Xfrontend -warn-missing-module-import -D OBJC_OLD_DISPATCH_PROTOTYPE=1 $(find. -name *.mm | grep -v Modules) 

Tips: 执行后,会自动在桌面生成 so 文件,注意需要将 so 文件放到 Application/Frameworks 中。

如果想手动修改代码的话:

在 Xcode 中,修改 OC 中的方法,增加类型标记即可,以这个方法为例:

- (NSString *)string;  

改成:

- (nonnull NSString *)string;

因为只是修改了OC代码,所以在使用OC代码的地方就会报警告:

Using the Objective-C method '_Nonnull NSString *string' on a Swift type.

解决方法是在 OC 代码的引入处添加 @objc

@objc interface UserInfo : NSObject

这里,我们只是把 String 类型加了非空标记,换做其他类型也一样,如果是类,可以直接用 nonnull 替换之前的 class

另外:

Xcode 预编译开关也很方便,比如增加 __has_feature(objc_arc) 来判断是否支持 ARC,结构如下:

#if __has_feature(objc_arc)
@interface Student : NSObject {
}

@property (nonnull, strong) NSString *name;
@property int age;

- (void)sayHello;
- (void)sayGoodbye;

@end
#else
@interface Student {
    NSString *_name;
    int _age;
}

@property (nonnull) NSString *name;
@property int age;

- (void)sayHello;
- (void)sayGoodbye;

@end
#endif

如果项目中使用到了 ARC,__has_feature(objc_arc) 为真,就会自动编译第一部分,否则,就编译第二部分。

或者用 #if __IPHONE_OS_VERSION_MIN_REQUIRED 来判断是哪个版本以上,结构如下:

#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_12_0
// for iOS 12 and later
#elif __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_11_0
// for iOS 11 and later
#else
// for iOS 10 and earlier
#endif

还可以使用 __TYPEOF__(type) 来判断某一个类型是否存在,如果存在,就会自动编译这一部分,否则,这一部分代码就不会被编译,结构如下:

#if __TYPEOF__(Foundation.NSLog)
NSLog(@"hello world!");
#else
printf("hello world!");
#endif

最后,如果不想手动修改代码,不想使用宏指令,或者想提高代码可读性,也可以使用 if #available 结构,结构如下:

if #available(iOS 10.0, *) {
    // Use iOS 10 APIs
} else {
    // Fallback to earlier iOS APIs
}

无论你是想消除警告,还是想优化代码结构,Xcode 提供了很多预编译开关宏命令,都可以满足你的需求。