SDWebImageCompat.h 头文件
#import <TargetConditionals.h>
/*
File: TargetConditionals.
Contains: Autoconfiguration of TARGET_ conditionals for Mac OS X and iPhone
Note: TargetConditionals.h in 3.4 Universal Interfaces works with all compilers. This header only recognizes compilers known to run on Mac OS X.
*/
引入编译器系统平台相关的控制宏定义。
#ifdef __OBJC_GC__
#error SDWebImage does not support Objective-C Garbage Collection
#endif
因为MacOS是支持GC的,当打开GC选项的时候,编译器就会定义这个宏__OBJC_GC__。因为SDWebImage只支持ARC所以,当启用GC时,编译器报错。详细的关于MacOS支持GC的问题,点击以下链接:developer.apple.com/documentati… 现在已转向ARC developer.apple.com/library/arc…
// Seems like TARGET_OS_MAC is always defined (on all platforms).
// To determine if we are running on macOS, use TARGET_OS_OSX in Xcode 8
#if TARGET_OS_OSX
#define SD_MAC 1
#else
#define SD_MAC 0
#endif
定义宏SD_MAC来识别编译平台是否为MacOS。
// iOS and tvOS are very similar, UIKit exists on both platforms
// Note: watchOS also has UIKit, but it's very limited
#if TARGET_OS_IOS || TARGET_OS_TV
#define SD_UIKIT 1
#else
#define SD_UIKIT 0
#endif
定义宏SD_UIKIT来识别编译平台是否支持UIKIT框架。
#if TARGET_OS_IOS
#define SD_IOS 1
#else
#define SD_IOS 0
#endif
定义宏SD_IOS来识别编译平台是否为IOS平台。
#if TARGET_OS_TV
#define SD_TV 1
#else
#define SD_TV 0
#endif
定义宏SD_TV来识别编译平台是否为TV OS。
#if TARGET_OS_WATCH
#define SD_WATCH 1
#else
#define SD_WATCH 0
#endif
定义宏SD_WATCH来识别编译平台是否为Watch OS。
#if SD_MAC
#import <AppKit/AppKit.h>
#ifndef UIImage
#define UIImage NSImage
#endif
#ifndef UIImageView
#define UIImageView NSImageView
#endif
#ifndef UIView
#define UIView NSView
#endif
#ifndef UIColor
#define UIColor NSColor
#endif
#else
#if SD_UIKIT
#import <UIKit/UIKit.h>
#endif
#if SD_WATCH
#import <WatchKit/WatchKit.h>
#ifndef UIView
#define UIView WKInterfaceObject
#endif
#ifndef UIImageView
#define UIImageView WKInterfaceImage
#endif
#endif
#endif
将<AppKit/AppKit.h>和<WatchKit/WatchKit.h>中功能及接口类似的组件使用统一的别名映射为UIView、UIImageView、UIColor。
#ifndef NS_ENUM
#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
#endif
#ifndef NS_OPTIONS
#define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type
#endif
如果不支持NS_ENUM和NS_OPTIONS宏,自定义支持这些宏,前向兼容。
#ifndef dispatch_main_async_safe
#define dispatch_main_async_safe(block)\
if (dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL) == dispatch_queue_get_label(dispatch_get_main_queue())) {\
block();\
} else {\
dispatch_async(dispatch_get_main_queue(), block);\
}
#endif
定义dispatch_main_async_safe()函数,如果当前队列已经是主队列,那么,就直接调用,相当于一种优化。
SDWebImageCompat.m实现文件
#import "SDWebImageCompat.h"
#if !__has_feature(objc_arc)
#error SDWebImage is ARC only. Either turn on ARC for the project or use -fobjc-arc flag
#endif
调用编译器函数,检查如果不支持ARC,编译器报错。
#if !OS_OBJECT_USE_OBJC
#error SDWebImage need ARC for dispatch object
#endif
GCD中的对象在6.0之前是不参与ARC,OS_OBJECT_USE_OBJC在SDK6.0之前是没有的。OS_OBJECT_USE_OBJC如果为1,那么ARC会自动管理(retain和release)dispatch_queue_t对象(适用于ios6以上);但是对于ios6.0以下你必须手动管理dispatch_queue_t对象,这个宏在这里是为了系统版本的兼容性。