其实这个问题就是集成不支持ARC的老OC代码和c代码遇到的问题。这几天因为要做点文本合并的工作,所以采用了google的diff-match-patch库。这个库比较老,不支持maven或pod仓库集成,所以要手工集成。
Android很快集成好了,但是集成iOS时遇到两个问题卡了半天,这里做个记录备忘。
第一个问题是Google代码中包含非ARC代码
这个问题比较好解决,因为编译时会类似于下面的错误:
/GoogleDiff/NSString+JavaSubstring.m:31:52: Cast of Objective-C pointer type 'NSString *' to C pointer type 'CFStringRef' (aka 'const struct __CFString *') requires a bridged cast
/GoogleDiff/NSString+JavaSubstring.m:31:53: Use __bridge to convert directly (no change in ownership)
/GoogleDiff/NSString+JavaSubstring.m:31:65: Use CFBridgingRetain call to make an ARC object available as a +1 'CFStringRef' (aka 'const struct __CFString *')
看到CFStringRef和__bridge字眼,有经验的童鞋基本可以确定问题原因了,解决方法是在对应的.m文件加上非arc标志,步骤:“project”->"Build Phases"->"Compile Sources"->xxx.m->"Compler Flags" 加上-fno-objc-arc
第二个问题是Google代码中包含C代码
这个问题也很好解决,但是如果之前没有这方面经验,靠报错很难定位错误原因。我这边很多系统库包类似于错误:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform
/Developer/SDKs/iPhoneOS12.1.sdk/System/Library/Frameworks
/Foundation.framework/Headers/NSObjCRuntime.h:515:9: Unknown type name 'NSString'
但是细心分析报错,终于找到一个自己项目中的文件xxxx-Prefix.h,然后这个文件中
#import <UIKit/UIKit.h>
这里报错提示 " Could not build module 'UIKit' ",
我们在"Build Settings"->"Prefix Header"中可以发现这个文件就是预编译头文件,也就是说所有文件编译时都会把这个头文件引入参与编译,.c和.cpp也不可避免,但是这个头文件里面引入了OC,而编译C和CPP时是不兼容OC语法的,所以就会报错。
解决办法就是使用如下的宏把预编译文件的代码包起来。
#ifdef __OBJC__
#endif
后续去搜索一些开源库的预编译文件,发现都有如下代码:
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
猜测应该是早期xcode项目会有默认模板处理类似问题,但是现在没有了,毕竟大家都开始用swift,现在连OC也快成老古董了。