美文网首页
读SDWebImageView源码笔记

读SDWebImageView源码笔记

作者: 喜欢就可以 | 来源:发表于2016-03-14 17:25 被阅读251次

    runtime category 属性

    - (NSMutableDictionary *)operationDictionary {
        NSMutableDictionary *operations = objc_getAssociatedObject(self, &loadOperationKey);
        if (operations) {
            return operations;
        }
        operations = [NSMutableDictionary dictionary];
        objc_setAssociatedObject(self, &loadOperationKey, operations, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        return operations;
    }
    

    通过宏定义安全线程

    #define dispatch_main_sync_safe(block)\
        if ([NSThread isMainThread]) {\
            block();\
        } else {\
            dispatch_sync(dispatch_get_main_queue(), block);\
        }
    
    #define dispatch_main_async_safe(block)\
        if ([NSThread isMainThread]) {\
            block();\
        } else {\
            dispatch_async(dispatch_get_main_queue(), block);\
        }
    

    通过宏控制ARC和非ARC下queue的释放和属性标识

    #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
    
    使用:
    @property (SDDispatchQueueSetterSementics, nonatomic) dispatch_queue_t ioQueue;
    
    - (void)dealloc {
        [[NSNotificationCenter defaultCenter] removeObserver:self];
        SDDispatchQueueRelease(_ioQueue);
    }
    
    

    在调试阶段可使用NSAssert判断nil

    // Invoking this method without a completedBlock is pointless
        NSAssert(completedBlock != nil, @"If you mean to prefetch the image, use -[SDWebImagePrefetcher prefetchURLs] instead");
    

    SDWebImageManager简单实现单单例

    /**
     * Returns global SDWebImageManager instance.
     *
     * @return SDWebImageManager shared instance
     */
    + (id)sharedManager {
        static dispatch_once_t once;
        static id instance;
        dispatch_once(&once, ^{
            instance = [self new];
        });
        return instance;
    }
    

    NSURL判断,容错NSString、NSNull

    // Very common mistake is to send the URL using NSString object instead of NSURL. For some strange reason, XCode won't
     // throw any warning for this type mismatch. Here we failsafe this error by allowing URLs to be passed as NSString.
     if ([url isKindOfClass:NSString.class]) {
            url = [NSURL URLWithString:(NSString *)url];
        }
    
    // Prevents app crashing on argument type error like sending NSNull instead of NSURL
        if (![url isKindOfClass:NSURL.class]) {
            url = nil;
        }
    

    使用NS_OPTIONS、NS_ENUM、typedef、block

    
    typedef NS_OPTIONS(NSUInteger, SDWebImageOptions) {
        /**
         * By default, when a URL fail to be downloaded, the URL is blacklisted so the library won't keep trying.
         * This flag disable this blacklisting.
         */
        SDWebImageRetryFailed = 1 << 0,
    
        /**
         * By default, image downloads are started during UI interactions, this flags disable this feature,
         * leading to delayed download on UIScrollView deceleration for instance.
         */
        SDWebImageLowPriority = 1 << 1,
    
        /**
         * This flag disables on-disk caching
         */
        SDWebImageCacheMemoryOnly = 1 << 2,
    
        /**
         * This flag enables progressive download, the image is displayed progressively during download as a browser would do.
         * By default, the image is only displayed once completely downloaded.
         */
        SDWebImageProgressiveDownload = 1 << 3,
    
    };
    
    typedef void(^SDWebImageCompletionBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL);
    typedef void(^SDWebImageCompletionWithFinishedBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL);
    typedef NSString *(^SDWebImageCacheKeyFilterBlock)(NSURL *url);
    

    if判断多使用短的这种有利于代码可读

      if (!doneBlock) {
            return nil;
        }
    
       if (!key) {
            doneBlock(nil, SDImageCacheTypeNone);
            return nil;
        }
    
        // First check the in-memory cache...
        UIImage *image = [self imageFromMemoryCacheForKey:key];
        if (image) {
            doneBlock(image, SDImageCacheTypeMemory);
            return nil;
        }
    

    block传值后应用copy关键字

    - (id)initWithRequest:(NSURLRequest *)request
                  options:(SDWebImageDownloaderOptions)options
                 progress:(SDWebImageDownloaderProgressBlock)progressBlock
                completed:(SDWebImageDownloaderCompletedBlock)completedBlock
                cancelled:(SDWebImageNoParamsBlock)cancelBlock {
        if ((self = [super init])) {
            _request = request;
            _shouldDecompressImages = YES;
            _shouldUseCredentialStorage = YES;
            _options = options;
            _progressBlock = [progressBlock copy];
            _completedBlock = [completedBlock copy];
            _cancelBlock = [cancelBlock copy];
            _executing = NO;
            _finished = NO;
            _expectedSize = 0;
            responseFromCached = YES; // Initially wrong until `connection:willCacheResponse:` is called or not called
        }
        return self;
    }
    

    相关文章

      网友评论

          本文标题:读SDWebImageView源码笔记

          本文链接:https://www.haomeiwen.com/subject/rtvflttx.html