汇编代码:

; 状态:R0 = imageFileName, R1 = mainBundle, R2 = isRetina

PUSH    {R4-R7,LR} ; R0 = imageFileName, R1 = mainBundle, R2 = isRetina

ADD      R7, SP, #0xC

PUSH.W  {R8,R10,R11}

STR.W    R2, [SP,#0x18+var_1C]!

MOV      R4, R0  ; R4 = R0 = imageFileName

MOV      R0, #(selRef_length - 0x17BB0) ; selRef_length

MOV      R10, R1 ; R10 = R1 = mainBundle

ADD      R0, PC ; selRef_length

LDR      R1, [R0] ; "length"

MOV      R0, R4  ; R0 = R4 = imageFileName

BLX.W    _objc_msgSend ; [imageFileName length]

MOVS     R6, #0  ; R6 = 0

CMP      R0, #0  ; check if R0 is 0

BEQ.W    loc_17D1C ; if R0 is 0, goto the label

MOV      R0, R4  ; R0 = R4 = imageFileName

MOV      R1, R10 ; R1 = R10 = mainBundle

BL     __UICacheNameForImageAtPath ; arg_0:imageFileName, arg_1:mainBundle, result:com.proteas.hello_Default.png

MOVW     R8, #(:lower16:(__MergedGlobals_36 - 0x17BD4))

MOV      R5, R0  ; R5 = R0 = imageCacheName

MOVT.W   R8, #(:upper16:(__MergedGlobals_36 - 0x17BD4))

ADD      R8, PC ; __MergedGlobals_36

ADD.W    R11, R8, #0x10 ; R11 = R8 + 16

MOV      R0, R11 ; lock, OSSpinLock*, 访问全局变量,加锁

BLX.W    _OSSpinLockLock ; arg_0: OSSpinLock*

LDR.W    R0, [R8,#(dword_62C524 - 0x62C510)] ; R0 = cachedImageMap, key:imageCacheName, value:UIImageObject

MOVS      R6, #0  ; R6 = 0

CBZ       R0, loc_17BEC ; if cachedImageMap is nil, goto the label

MOV       R1, R5  ; R1 = R5 = imageCacheName

BLX.W _CFDictionaryGetValue ; CFDictionaryGetValue(cachedImageMap, imageCacheName)

MOV       R6, R0  ; R6 = R0 = cachedUIImageObject

loc_17BEC:

MOV       R0, #(selRef_retainCount - 0x17BF8) ; selRef_retainCount

ADD       R0, PC ; selRef_retainCount

LDR       R1, [R0] ; "retainCount"

MOV       R0, R6  ; R0 = R6 = cachedUIImageObject

BLX.W     _objc_msgSend ; [cachedUIImageObject retainCount]

CBNZ     R0, loc_17C08 ; if retainCount of cachedUIImageObject is not 0, goto the label

MOV      R0, R11 ; lock

BLX.W    _OSSpinLockUnlock

B        loc_17C50

loc_17C08:

MOV      R0, #(selRef__isCached - 0x17C14) ; selRef__isCached

ADD      R0, PC ; selRef__isCached

LDR      R1, [R0] ; R1 = "_isCached"

MOV      R0, R6  ; R0 = R6 = cachedUIImageObject

BLX.W    _objc_msgSend ; R0 = isCached

TST.W    R0, #0xFF ; check if R0 is true

BNE      loc_17C46 ; if not cached, goto the label

MOV      R0, #(selRef_retain - 0x17C2C) ; selRef_retain

ADD      R0, PC ; selRef_retain

LDR      R1, [R0] ; "retain"

MOV      R0, R6  ; R0 = R6 = cachedUIImageObject

BLX.W    _objc_msgSend ; [cachedUIImageObject retain]

MOVW     R0, #(:lower16:(selRef__setCached_ - 0x17C40))

MOVS     R2, #1  ; R2 = 1

MOVT.W   R0, #(:upper16:(selRef__setCached_ - 0x17C40))

ADD      R0, PC ; selRef__setCached_

LDR      R1, [R0] ; "_setCached:"

MOV      R0, R6  ; R0 = R6 = cachedUIImageObject

BLX.W    _objc_msgSend ; [cachedUIImageObject _setCached:YES]

loc_17C46:

MOV      R0, R11 ; lock

BLX.W    _OSSpinLockUnlock ; 释放锁

CMP      R6, #0  ; check if cachedUIImageObject is nil

BNE      loc_17D1C ; if not nil, goto the label

loc_17C50:

MOVW     R3, #(:lower16:(_GetImageAtPath+1 - 0x17C60))

MOV      R0, R4  ; R0 = R4 = imageFileName

MOVT.W   R3, #(:upper16:(_GetImageAtPath+1 - 0x17C60))

LDR      R2, [SP,#0x1C+var_1C] ; R2 = isRetina

ADD      R3, PC ; _GetImageAtPath ; R3 = _GetImageAtPath

MOV      R1, R10 ; R1 = R10 = mainBundle

BL    __UIImageCallFunctionForAppropriatePath ; arg_0:imageFileName, arg_1 = mainBundle, arg_2 = isRetina, arg_3 = _GetImageAtPath

MOV      R6, R0  ; R6 = R0 = UIImageObject

CMP      R6, #0  ; check if UIImageObject is nil

BEQ      loc_17D1C ; if failed, goto label

MOV      R0, R11 ; lock

BLX.W    _OSSpinLockLock

LDR.W    R0, [R8,#0x14] ; R0 = pointer to imageCacheMap

CBNZ     R0, loc_17CAE ; R1 = R5 = imageCacheName

MOVW     R0, #(:lower16:(_kCFTypeDictionaryKeyCallBacks_ptr - 0x17C86))

MOVS     R1, #0  ; R1 = capacity = 0

MOVT.W R0, #(:upper16:(_kCFTypeDictionaryKeyCallBacks_ptr - 0x17C86))

MOVS     R3, #0  ; R3 = valueCallBacks = 0

ADD      R0, PC ; _kCFTypeDictionaryKeyCallBacks_ptr

LDR      R2, [R0] ; _kCFTypeDictionaryKeyCallBacks

MOVS     R0, #0  ; R0 = allocator = NULL

BLX.W    _CFDictionaryCreateMutable ; R0 = cachedImageMap

MOVW     R1, #(:lower16:(_kCFTypeDictionaryValueCallBacks_ptr - 0x17C9E))

MOVS     R2, #0  ; R2 = keyCallBacks = NULL

MOVT.W          R1, #(:upper16:(_kCFTypeDictionaryValueCallBacks_ptr - 0x17C9E))

STR.W   R0, [R8,#0x14]

ADD      R1, PC ; _kCFTypeDictionaryValueCallBacks_ptr

MOVS     R0, #0  ; R0 = allocator = NULL

LDR      R3, [R1] ; _kCFTypeDictionaryValueCallBacks

MOVS     R1, #0  ; R1 = capacity = 0

BLX.W    _CFDictionaryCreateMutable

STR.W    R0, [R8,#0x18]

LDR.W    R0, [R8,#0x14]

loc_17CAE:

MOV      R1, R5  ; R1 = R5 = imageCacheName

BLX.W    _CFDictionaryContainsKey

CBNZ     R0, loc_17CF8 ; if has cached, goto the label

MOVW     R0, #(:lower16:(selRef__setNamed_ - 0x17CC4))

MOVS     R2, #1  ; R2 = YES

MOVT.W   R0, #(:upper16:(selRef__setNamed_ - 0x17CC4))

ADD      R0, PC ; selRef__setNamed_

LDR      R1, [R0] ; "_setNamed:"

MOV      R0, R6  ; R0 = R6 = UIImageObject

BLX.W    _objc_msgSend ; [UIImageObject _setNamed:YES]

MOVW     R0, #(:lower16:(selRef__setCached_ - 0x17CD8))

MOVS     R2, #1

MOVT.W   R0, #(:upper16:(selRef__setCached_ - 0x17CD8))

ADD      R0, PC ; selRef__setCached_

LDR      R1, [R0] ; "_setCached:"

MOV      R0, R6

BLX.W   _objc_msgSend ; [UIImageObject _setCached:YES]

LDR.W    R0, [R8,#0x14] ; R0 = cachedImageMap

MOV      R1, R5  ; R1 = R5 = imageCacheName

MOV      R2, R6  ; R2 = R6 = UIImageObject

BLX.W   _CFDictionarySetValue ; arg_0:cachedImageMap, arg_1 = imageCacheName, arg_2 = imageObject

LDR.W    R0, [R8,#0x18]

MOV      R1, R6  ; R1 = R6 = UIImageObject

MOV      R2, R5  ; R2 = R5 = imageCacheName

BLX.W  _CFDictionarySetValue ; arg_0: dictionary, arg_1: imageObject, arg_2 = imageCacheName

B        loc_17D16

loc_17CF8:

MOV     R0, #(selRef_release - 0x17D04) ; selRef_release

ADD     R0, PC ; selRef_release

LDR     R1, [R0] ; "release"

MOV     R0, R6  ; R0 = R6 = UIImageObject

BLX.W  _objc_msgSend ; [UIImageObject release]

LDR.W  R0, [R8,#0x14] ; R0 = cachedImageMap

MOV    R1, R5  ; R1 = R5 = imageCacheName

BLX.W  _CFDictionaryGetValue

MOV    R6, R0  ; R6 = R0 = result UIImage instance

loc_17D16:

MOV    R0, R11 ; lock

BLX.W  _OSSpinLockUnlock ; release spin lock

loc_17D1C:

MOV    R0, R6  ; R0 = R6 = nil

ADD    SP, SP, #4

POP.W  {R8,R10,R11}

POP     {R4-R7,PC}

伪代码:

NSDictionary *gCachedImageMapNameToImage = nil;

NSDictionary *gCachedImageMapImageToName = nil;

_UIImageAtPath(NSString *imageFileName, NSBundle *mainBundle, BOOL isRetina) {

if ([imageFileName length] == 0)

returnnil;

if (gCachedImageMapNameToImage == nil) {

gCachedImageMapNameToImage = [[NSMutableDictionaryalloc] init];

gCachedImageMapImageToName = [[NSMutableDictionaryalloc] init];

}

NSString *imageCacheName = _UICacheNameForImageAtPath(imageFileName, mainBundle);

UIImage *cachedImage = [gCachedImageMapNameToImageobjectForKey:imageCacheName];

if (cachedImage == nil) {

cachedImage = _UIImageCallFunctionForAppropriatePath(imageFileName, mainBundle, isRetina, _UIImageAtPath);

if (cachedImage == nil) {

returnnil;

} else {

[gCachedImageMapNameToImagesetObject:cachedImage forKey:imageCacheName];

[gCachedImageMapImageToNamesetObject:imageCacheName forKey:cachedImage];

[cachedImage _setNamed:YES];

[cachedImage _setCached:YES];

}

} else {

if (![cachedImage _isCached]) {

[cachedImage _setCached:YES];

}

}

return cachedImage;

}

最新文章

  1. rxjs5.X系列 —— filter系列 api 笔记
  2. AOJ 0558 Cheese【BFS】
  3. Ionic2学习笔记(8):Local Storage& SQLite
  4. python, itertools模块
  5. [ES6] 19. for ... of
  6. Android SDK 和 Eclipse ADT 离线安装 教程
  7. Spring配置与第一Spring HelloWorld
  8. utf8 和 UTF-8 在使用中的差别
  9. php中的session_id详解
  10. win10系统电脑常用基本操作快捷键
  11. AtCoder Regular Contest 077 E - guruguru
  12. 题目1015:还是A+B(简单判断)
  13. ERROR org.redisson.client.handler.CommandDecoder - Unable to decode data. channel
  14. C/C++基础----随机数分布和随机数引擎
  15. zoj3814
  16. python中join()函数、list()函数补充的用法
  17. COGS 栅格网络流
  18. Work-Stealing in .NET 4.0
  19. Codeforces Round #335 (Div. 2) D. Lazy Student 贪心+构造
  20. python把中文文档变为拼音

热门文章

  1. jquery中DOM的操作方法
  2. 基于 Android 的 3D 视频样本代码
  3. POJ 2586 Y2K Accounting Bug(枚举洪水问题)
  4. javascript系列之核心知识点(二)
  5. HTML的标签canvas
  6. HDU 5068 Harry And Math Teacher
  7. .net mvc mssql easyui treegrid
  8. openfire修改服务器名称方法
  9. Yii Framework2.0开发教程(4)在yii中定义全局变量
  10. javascript 验证 yyyy-MM-dd HH:mm:ss 的正则表达式