OC代码条件编译

2019-06-19  本文已影响0人  codingchou
做个记录,方便自己查看

条件编译只能决定编译阶段代码是否编译,并不能决定运行时的逻辑,还需要结合具体系统版本判断
if (@available(iOS 12.0, *)) {
code...
}

1、#if的使用说明
#if的后面接的是表达式
#if (MAX==10)||(MAX==20)
code...
#endif

它的作用是:如果(MAX==10)||(MAX==20)成立,那么编译器就会把其中的#if 与 #endif之间的代码编译进去(注意:是编译进去,不是执行!!)
#if defined的使用
#if后面接的是一个宏。


2、#if defined (x)
code...
#endif
这个#if defined它不管里面的“x”的逻辑是“真”还是“假”它只管这个程序的前面的宏定义里面有没有定义“x”这个宏,如果定义了x这个宏,那么,编译器会编译中间的…code…否则不直接忽视中间的…code…代码。
另外 #if defined(x)也可以取反,也就用 #if !defined(x)


3、#ifdef的使用
#ifdef的使用和#if defined()的用法一致
#ifndef又和#if !defined()的用法一致。
最后强调两点:
第一:这几个宏定义只是决定代码块是否被编译!
第二:别忘了#endif


4、#ifndef 的使用
#ifndef _XXXX 
  code...
#else 
  code...
#endif


5、使用案例

//可以通过逻辑与判断多个条件
#if defined(DEBUG) && DEBUG
@property (nonatomic, weak) id<FLAnimatedImageViewDebugDelegate> debug_delegate;
#endif

//判断单个条件
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else

//嵌套使用
#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



// 条件编译分支 #elif
// 以下示例中的条件编译语句假定一个名为 DLEVEL 的之前定义的符号常量。
#if DLEVEL > 5
    #define SIGNAL  1
    #if STACKUSE == 1
        #define STACK   200
    #else
        #define STACK   100
    #endif
#else
    #define SIGNAL  0
    #if STACKUSE == 1
        #define STACK   100
    #else
        #define STACK   50
    #endif
#endif
#if DLEVEL == 0
    #define STACK 0
#elif DLEVEL == 1
    #define STACK 100
#elif DLEVEL > 5
    display( debugptr );
#else
    #define STACK 200
#endif



//具体路径为: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/Availability.h 

#define __IPHONE_2_0      20000
#define __IPHONE_2_1      20100
#define __IPHONE_2_2      20200
#define __IPHONE_3_0      30000
#define __IPHONE_3_1      30100
#define __IPHONE_3_2      30200
#define __IPHONE_4_0      40000
#define __IPHONE_4_1      40100
#define __IPHONE_4_2      40200
#define __IPHONE_4_3      40300
#define __IPHONE_5_0      50000
#define __IPHONE_5_1      50100
#define __IPHONE_6_0      60000
#define __IPHONE_6_1      60100
#define __IPHONE_7_0      70000
#define __IPHONE_7_1      70100
#define __IPHONE_8_0      80000
#define __IPHONE_8_1      80100
#define __IPHONE_8_2      80200
#define __IPHONE_8_3      80300
#define __IPHONE_8_4      80400
#define __IPHONE_9_0      90000
#define __IPHONE_9_1      90100
#define __IPHONE_9_2      90200
#define __IPHONE_9_3      90300
#define __IPHONE_10_0    100000
#define __IPHONE_10_1    100100
#define __IPHONE_10_2    100200
#define __IPHONE_10_3    100300
#define __IPHONE_11_0    110000
#define __IPHONE_11_1    110100
#define __IPHONE_11_2    110200
#define __IPHONE_11_3    110300
#define __IPHONE_11_4    110400
#define __IPHONE_12_0    120000
#define __IPHONE_12_1    120100
#define __IPHONE_12_2    120200

///这些系统版本宏。如果在比较低的sdk 中是没有定义的,这时可以直接使用数字

__IPHONE_OS_VERSION_MAX_ALLOWED   这个宏得到的是当前开发环境的系统SDK版本
__IPHONE_OS_VERSION_MIN_REQUIRED  这个宏它是当前项目选择的最低支持的版本


#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
// 在 iOS10.0 及以上的开发环境 编译此部分代码
#else
// 在低于 iOS10.0 的开发环境 编译此部分代码
#endif

#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0
// 如果选择(iOS Deployment Target)的最低支持版本在iOS8.0及以上才可以使用
- (void)execute;
#endif



///判断真机或者模拟器
TARGET_IPHONE_SIMULATOR 或 TARGET_OS_IPHONE 来区分

#if TARGET_OS_IPHONE
    NSLog(@"真机");
    self.ijkPlayer = [[CHPIJKPlayerManager alloc] init];
    
    self.playerController = [CHPlayerController playerWithPlayerManager:self.ijkPlayer containerView:self.playerFahterView];
    [self.playerController setControlView:self.controlView];
    
    self.playerController.assetURL = [NSURL URLWithString:TestUrl];
    
    [self.controlView showTitle:@"我是标题" coverImage:[UIImage new]];
#else
    NSLog(@"模拟器");
#endif

//iOS 11.0 以上的SDK编译,跟下面的代码等价
#ifdef __IPHONE_11_0
#import <ReplayKit/ReplayKit.h>
#endif

#if defined(__IPHONE_11_0)
#import <ReplayKit/ReplayKit.h>
#endif
#if defined(__IPHONE_12_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_12_0)
@property (nonatomic, strong) RPSystemBroadcastPickerView *broadPickerView API_AVAILABLE(ios(12.0));
#endif
#endif

//示例一:
- (UICollectionViewFlowLayout *)flowLayout {
    if (!_flowLayout) {
        _flowLayout = [[UICollectionViewFlowLayout alloc] init];
        _flowLayout.minimumInteritemSpacing = 0;
        _flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
        
        if (self.outside) {
            _flowLayout.sectionInset = UIEdgeInsetsMake(0, 10, 0, 10);
        }else {
#ifdef __IPHONE_11_0
            if (@available(iOS 11.0, *)) {
#else
                if ((NO)) {
#endif
                    _flowLayout.sectionInset = UIEdgeInsetsMake(0, 10, 0, 10);
                }else {
                    _flowLayout.sectionInset = UIEdgeInsetsMake(0, 10, 0, 10);
                }
            }
        }
        return _flowLayout;
    }



//示例二:
- (void)startSystemRecording:(UIViewController *)inVC {
    if (!inVC) {
        return;
    }
    
    
#if defined(__IPHONE_12_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_12_0)
    if (@available(iOS 12.0, *)) {  //加判断是为了消除警告
        _broadPickerView = [[RPSystemBroadcastPickerView alloc] initWithFrame:CGRectMake(200, 200, 60, 60)];
        _broadPickerView.preferredExtension = BrocastExtension;
        _broadPickerView.showsMicrophoneButton = NO;
        [_broadPickerView setBackgroundColor:[UIColor orangeColor]];
        [inVC.view addSubview:_broadPickerView];
    }
#else
    
    NSString *appname = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
    
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:appname message:@"开启系统界面录制,请先到控制中心->长按录制按钮开启" preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *ok = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
    }];
    
    [alert addAction:ok];
    [inVC presentViewController:alert animated:YES completion:nil];
    
#endif
}
头文件的导入判断
#if __has_include(<SDWebImage/UIImageView+WebCache.h>)
#import <SDWebImage/UIImageView+WebCache.h>
#else
#import "UIImageView+WebCache.h"
#endif
参考博客

#if、#elif、#else 和 #endif 指令详解 (C/C++)
条件编译 -- TARGET_OS_IPHONE

上一篇 下一篇

猜你喜欢

热点阅读