SDWebImage之SDWebImageCompat
SDWebImageCompat 是SDWebImage 的配置文件,里面利用条件编译对Apple 的各个平台进行了兼容。从源码中可以看到SDWebImage 支持当前的MAC/iOS/TV/WATCH 平台,这种适配各个平台的兼容,对框架开发意义重大。
1.#import <TargetConditionals.h>
导入这个头文件,能访问系统提供的配置选项。这个文件里面全部都是宏定义,主要定义了Apple 各系统平台和各CPU类型相关的宏。主要用于开发的时候针对不同的开发环境做配置使用。
2.条件编译__OBJC_GC__
#ifdef __OBJC_GC__
#error SDWebImage does not support Objective-C Garbage Collection
#endif
Objective-C 支持内存的垃圾回收机制(Garbage collection 简称:GC)。在Mac开发是支持的,但是在iOS 开发中使用MRC/ARC,是不支持GC 的。iOS 5 之后开始支持ARC ,帮助开发者更好的管理内存,简化内存管理的难度并提高开发效率。SDWebImage 不支持GC,如果宏定义过 __OBJC_GC__,则表示是在支持GC 的开发环境,直接报错(#error)。当启动GC时,所有的retain、autorelease、release 和dealloc 方法都将被系统忽略。
3.SD_MAC
#if !TARGET_OS_IPHONE && !TARGET_OS_IOS && !TARGET_OS_TV && !TARGET_OS_WATCH
#define SD_MAC 1
#else
#define SD_MAC 0
#endif
判断当前平台是不是MAC。TARGET_OS_MAC 定义在所有的平台中,比如MAC、iPhone、Watch、TV等,因此单纯的使用TARGET_OS_MAC 判断当前是不是MAC 平台是不可行的。但按照上面的判断方式,也存在一个缺点:当Apple出现新的平台时,判断条件要修改。
4.SD_UIKIT
#if TARGET_OS_IOS || TARGET_OS_TV
#define SD_UIKIT 1
#else
#define SD_UIKIT 0
#endif
iOS 和 tvOS 是非常相似的,UIKit在这两个平台中都存在,但是watchOS在使用UIKit时,是受限的。因此定义SD_UIKIT为真的条件是iOS 和 tvOS这两个平台。
5.SD_IOS&&SD_TV&&SD_WATCH
#if TARGET_OS_IOS
#define SD_IOS 1
#else
#define SD_IOS 0
#endif #if TARGET_OS_TV
#define SD_TV 1
#else
#define SD_TV 0
#endif #if TARGET_OS_WATCH
#define SD_WATCH 1
#else
#define SD_WATCH 0
#endif
这三个宏定义用于区分iOS、TV、WATCH三个平台。
6.平台兼容适配
#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
#else
//SDWebImage不支持5.0以下的iOS版本
#if __IPHONE_OS_VERSION_MIN_REQUIRED != 20000 && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0
#error SDWebImage doesn't support Deployment Target version < 5.0
#endif #if SD_UIKIT
#import <UIKit/UIKit.h>
#endif
#if SD_WATCH
#import <WatchKit/WatchKit.h>
#endif
#endif
- 如果SD_MAC 为真,表示在macOS 平台上开发,引入 并定义了三个宏 UIImage/UIImageView/UIView;
- SDWebImage 不支持iOS 5.0 以下的版本;
- SD_UIKIT 为真时引入 <UIKit/UIKit.h>;
- SD_WATCH 为真时引入 <WatchKit/WatchKit.h>。
7. NS_ENUM/NS_OPTIONS
#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
用于枚举类型。
8.OS_OBJECT_USE_OBJC
#if OS_OBJECT_USE_OBJC
#undef SDDispatchQueueRelease
#undef SDDispatchQueueSetterSementics
#define SDDispatchQueueRelease(q)
#define SDDispatchQueueSetterSementics strong
#else
#undef SDDispatchQueueRelease
#undef SDDispatchQueueSetterSementics
#define SDDispatchQueueRelease(q) (dispatch_release(q))
#define SDDispatchQueueSetterSementics assign
#endif
OS_OBJECT_USE_OBJC宏定义是在6.0版本之后才出现的。该宏定义主要是针对GCD 的,GCD 中的对象在6.0之前是不参与ARC的,而6.0之后 在ARC下使用GCD不用关心释放问题。 对于最低sdk 版本 >= iOS 6.0来说,GCD 对象已经纳入了ARC 的管理范围,我们就不需要再手工调用 dispatch_release 了;否则的话,在sdk < 6.0的时候;即使开启了ARC ,这个宏OS_OBJECT_USE_OBJC 也是没有的,也就是说这个时候,GCD对象还必须得自己管理。
如果开发的项目最低目标低于 iOS 6.0 or Mac OS X 10.8,应该自己管理GCD对象;使用(dispatch_retain ,dispatch_release),ARC 并不会去管理它们。
如果开发的项目最低目标是 iOS 6.0 or Mac OS X 10.8 或者更高的,ARC 已经能够管理GCD 对象了,这时候GCD 对象就如同普通的OC 对象一样,不应该使用dispatch_retain , ordispatch_release 。
9.API
//给定一张图片,通过参数key调整scale属性,返回对应分辨率下面的图片
extern UIImage *SDScaledImageForKey(NSString *key, UIImage *image); typedef void(^SDWebImageNoParamsBlock)(); extern NSString *const SDWebImageErrorDomain; static int64_t kAsyncTestTimeout = ;
10.dispatch_main_async_safe
#ifndef dispatch_main_async_safe
#define dispatch_main_async_safe(block)\
if (strcmp(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
在主线程中安全的执行任务Block。
在项目中,如果当前线程已经是主线程,那么在调用dispatch_async(dispatch_get_main_queue(), block)有可能会出现crash。因此做了一个判断:当前线程是主线程,直接调用Block;如果不是,那么调用dispatch_async(dispatch_get_main_queue(), block)。
11.全局方法SDScaledImageForKey
/**
给定一张图片,通过参数key调整scale属性,返回对应分辨率下面的图片 @param key 图片名称
@param image 资源图片
@return 处理以后的图片
*/
inline UIImage *SDScaledImageForKey(NSString * _Nullable key, UIImage * _Nullable image) {
//异常处理
if (!image) {
return nil;
} #if SD_MAC
return image;
#elif SD_UIKIT || SD_WATCH
//如果是动态图片,比如GIF图片,则迭代处理
if ((image.images).count > ) {
NSMutableArray<UIImage *> *scaledImages = [NSMutableArray array];
//迭代处理每一张图片
for (UIImage *tempImage in image.images) {
[scaledImages addObject:SDScaledImageForKey(key, tempImage)];
}
//把处理结束的图片再合成一张动态图片
return [UIImage animatedImageWithImages:scaledImages duration:image.duration];
}
else {
#if SD_WATCH
if ([[WKInterfaceDevice currentDevice] respondsToSelector:@selector(screenScale)]) {
#elif SD_UIKIT
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
#endif
CGFloat scale = ;
// “@2x.png”的长度为7,所以此处添加了这个判断,很巧妙
if (key.length >= ) {
NSRange range = [key rangeOfString:@"@2x."];
if (range.location != NSNotFound) {
scale = 2.0;
} range = [key rangeOfString:@"@3x."];
if (range.location != NSNotFound) {
scale = 3.0;
}
}
//返回对应分辨率下面的图片
UIImage *scaledImage = [[UIImage alloc] initWithCGImage:image.CGImage scale:scale orientation:image.imageOrientation];
image = scaledImage;
}
return image;
}
#endif
}
SDWebImage之SDWebImageCompat的更多相关文章
- SDWebImage源码分析
1.概述 SDWebImage是iOS开发中,被广泛使用的一个第三方开源库,提供了图片从加载.解析.处理.缓存.清理等一些列功能,让我们能够专心于业务的处理.本篇会从SDWebImage的源码,来一步 ...
- SDWebImage源码解读 之 SDWebImageCompat
第三篇 前言 本篇主要解读SDWebImage的配置文件.正如compat的定义,该配置文件主要是兼容Apple的其他设备.也许我们真实的开发平台只有一个,但考虑各个平台的兼容性,对于框架有着很重要的 ...
- SDWebImage源码解读之SDWebImageDownloaderOperation
第七篇 前言 本篇文章主要讲解下载操作的相关知识,SDWebImageDownloaderOperation的主要任务是把一张图片从服务器下载到内存中.下载数据并不难,如何对下载这一系列的任务进行设计 ...
- SDWebImage源码解读_之SDWebImageDecoder
第四篇 前言 首先,我们要弄明白一个问题? 为什么要对UIImage进行解码呢?难道不能直接使用吗? 其实不解码也是可以使用的,假如说我们通过imageNamed:来加载image,系统默认会在主线程 ...
- SDWebImage源码解读之SDWebImageCache(上)
第五篇 前言 本篇主要讲解图片缓存类的知识,虽然只涉及了图片方面的缓存的设计,但思想同样适用于别的方面的设计.在架构上来说,缓存算是存储设计的一部分.我们把各种不同的存储内容按照功能进行切割后,图片缓 ...
- SDWebImage源码解读之SDWebImageCache(下)
第六篇 前言 我们在SDWebImageCache(上)中了解了这个缓存类大概的功能是什么?那么接下来就要看看这些功能是如何实现的? 再次强调,不管是图片的缓存还是其他各种不同形式的缓存,在原理上都极 ...
- 【原】SDWebImage源码阅读(四)
[原]SDWebImage源码阅读(四) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 SDWebImage中主要实现了NSURLConnectionDataDelega ...
- IOS 使用SDWebImage实现仿新浪微博照片浏览器
使用第三方库SDWebImage实现仿新浪微博照片浏览器,可以下载图片缓存,点击之后滚动查看相片,具体效果如下: 代码如下: WeiboImageView.h: #import <UIKit/U ...
- SDWebImage源码解读之SDWebImageDownloader
SDWebImage源码解读之SDWebImageDownloader 第八篇 前言 SDWebImageDownloader这个类非常简单,作者的设计思路也很清晰,但是我想在这说点题外话. 如果有人 ...
随机推荐
- 多线程利器-队列(queue)
#队列有3中模式,先进先出,先进后出,优先级 1:先进先出import queue q = queue.Queue() #默认是先进先出q.put(12)q.put('jack')q.put({'na ...
- mysql const与eq_ref的区别
简单地说是const是直接按主键或唯一键读取,eq_ref用于联表查询的情况,按联表的主键或唯一键联合查询. 下面的内容翻译自官方方档: const该表最多有一个匹配行, 在查询开始时读取.由于只有一 ...
- Linux:sudo,没有找到有效的 sudoers 资源。
首先,这是因为用户的权限不够导致的. 使用 ls -l /etc/passwd 查看所有用户及权限.只有可读权限(r),说明用户的权限不够. 因此,我们可以用以下方法修改用户权限: 1. su roo ...
- install mysql from source and troubleshooting example
I tried to install MySQL 5.7 from source file and upgrading previous MySQL version to the lastest 5. ...
- 2018面向对象程序设计(Java)第18周学习指导及要求
2018面向对象程序设计(Java) 第18周学习指导及要求(2018.12.27-2018.12.30) 学习目标 (1) 综合掌握java基本程序结构: (2) 综合掌握java面向对象程序设 ...
- idea常用快捷键及操作
ctrl+j ===== 智能提示 可用模版及关键字 ctrl+p ===== 显示方法可填入的参数 ctrl+space ===== 补全提示项目中可用的变量 ctrl+shift+j ==== ...
- Servlet中获取Spring管理的bean
描述: 在Servlet中调用Spring管理的接口,可以使Dao/Service/ServiceImpl. 前提是在调用的bean中有注解: @Repository("beanName&q ...
- 《CSAPP》虚拟存储器
虚拟存储器与物理存储器 虚拟存储器(VM)被组织为一个由存放在磁盘上的N个连续的字节大小的单元组成的数组.每一个字节都有一个唯一的虚拟地址,这个唯一的虚拟地址作为数组的索引.磁盘上的数组内容被缓存在主 ...
- 最小生成树求最大比率 UVALive - 5713
题目链接:https://vjudge.net/problem/UVALive-5713 题意:给出t组数据,每组数据第一行给出一个n,表示点的数量,接下来n行,每行有三个数字,分别是点的坐标x,y和 ...
- oracle 新增并返回新增的主键
oracle 的insert into 语句需要返回新增的主键的时候,可以使用一下insert 语法: insert into ims.t_bank_inquire_results (t_date,l ...