Skip to content

Commit 9d98639

Browse files
authored
Update to v2.12.1 (#42)
- Fix bugs related to capping the sizes of caches - Capping a cache to `0` bytes would not completely disable it as documented, fixed - Setting the max ratio value to a negative value would not use the default value as documented, fixed - Thanks to @jml5qh for filing this issue (#41) - Analyzer warning fixes too (not actual bugs)
1 parent 8b3eff1 commit 9d98639

17 files changed

+202
-97
lines changed

CHANGELOG.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,21 @@
22

33
## Info
44

5-
**Document version:** 2.12.0
5+
**Document version:** 2.12.1
66

7-
**Last updated:** 12/18/2018
7+
**Last updated:** 01/22/2018
88

99
**Author:** Nolan O'Brien
1010

1111
## History
1212

13+
### 2.12.1
14+
15+
- Fix bugs related to capping the sizes of caches
16+
- Capping a cache to `0` bytes would not completely disable it as documented, fixed
17+
- Setting the max ratio value to a negative value would not use the default value as documented, fixed
18+
- Thanks to @jml5qh for filing this issue (#41)
19+
1320
### 2.12.0
1421

1522
- Add `TIPImageTypeHEIC` and `TIPImageTypeAVCI` support

TwitterImagePipeline.podspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Pod::Spec.new do |s|
22
s.name = 'TwitterImagePipeline'
3-
s.version = '2.12.0'
4-
s.compiler_flags = '-DTIP_PROJECT_VERSION=2.12.0'
3+
s.version = '2.12.1'
4+
s.compiler_flags = '-DTIP_PROJECT_VERSION=2.12'
55
s.summary = 'Twitter Image Pipeline is a robust and performant image loading and caching framework for iOS'
66
s.description = 'Twitter created a framework for image loading/caching in order to fulfill the numerous needs of Twitter for iOS including being fast, safe, modular and versatile.'
77
s.homepage = 'https://github.com/twitter/ios-twitter-image-pipeline'

TwitterImagePipeline.xcodeproj/project.pbxproj

Lines changed: 4 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,10 +1305,9 @@
13051305
isa = PBXNativeTarget;
13061306
buildConfigurationList = 8B6511D92135DE7300ED057B /* Build configuration list for PBXNativeTarget "TwitterImagePipeline.framework tvOS" */;
13071307
buildPhases = (
1308+
8B6511BB2135DE7300ED057B /* Headers */,
13081309
8B6511952135DE7300ED057B /* Sources */,
13091310
8B6511BA2135DE7300ED057B /* Frameworks */,
1310-
8B6511BB2135DE7300ED057B /* Headers */,
1311-
8B6511D82135DE7300ED057B /* Resources */,
13121311
);
13131312
buildRules = (
13141313
);
@@ -1323,10 +1322,9 @@
13231322
isa = PBXNativeTarget;
13241323
buildConfigurationList = 8B6511F82135DEB400ED057B /* Build configuration list for PBXNativeTarget "TIPTests tvOS" */;
13251324
buildPhases = (
1325+
8B6511F12135DEB400ED057B /* Headers */,
13261326
8B6511E12135DEB400ED057B /* Sources */,
13271327
8B6511ED2135DEB400ED057B /* Frameworks */,
1328-
8B6511F12135DEB400ED057B /* Headers */,
1329-
8B6511F72135DEB400ED057B /* Resources */,
13301328
);
13311329
buildRules = (
13321330
);
@@ -1379,10 +1377,9 @@
13791377
isa = PBXNativeTarget;
13801378
buildConfigurationList = 8BA9755C1D77E2CA00601D70 /* Build configuration list for PBXNativeTarget "TIPTests" */;
13811379
buildPhases = (
1380+
8BA975501D77E2C900601D70 /* Headers */,
13821381
8BA9754E1D77E2C900601D70 /* Sources */,
13831382
8BA9754F1D77E2C900601D70 /* Frameworks */,
1384-
8BA975501D77E2C900601D70 /* Headers */,
1385-
8BA975511D77E2C900601D70 /* Resources */,
13861383
);
13871384
buildRules = (
13881385
);
@@ -1471,10 +1468,9 @@
14711468
isa = PBXNativeTarget;
14721469
buildConfigurationList = 8BFF17751DF5B4AD005DE734 /* Build configuration list for PBXNativeTarget "TwitterImagePipeline.framework" */;
14731470
buildPhases = (
1471+
8BFF17671DF5B4AD005DE734 /* Headers */,
14741472
8BFF17651DF5B4AD005DE734 /* Sources */,
14751473
8BFF17661DF5B4AD005DE734 /* Frameworks */,
1476-
8BFF17671DF5B4AD005DE734 /* Headers */,
1477-
8BFF17681DF5B4AD005DE734 /* Resources */,
14781474
);
14791475
buildRules = (
14801476
);
@@ -1577,20 +1573,6 @@
15771573
);
15781574
runOnlyForDeploymentPostprocessing = 0;
15791575
};
1580-
8B6511D82135DE7300ED057B /* Resources */ = {
1581-
isa = PBXResourcesBuildPhase;
1582-
buildActionMask = 2147483647;
1583-
files = (
1584-
);
1585-
runOnlyForDeploymentPostprocessing = 0;
1586-
};
1587-
8B6511F72135DEB400ED057B /* Resources */ = {
1588-
isa = PBXResourcesBuildPhase;
1589-
buildActionMask = 2147483647;
1590-
files = (
1591-
);
1592-
runOnlyForDeploymentPostprocessing = 0;
1593-
};
15941576
8B65120B2135DFC600ED057B /* Resources */ = {
15951577
isa = PBXResourcesBuildPhase;
15961578
buildActionMask = 2147483647;
@@ -1619,13 +1601,6 @@
16191601
);
16201602
runOnlyForDeploymentPostprocessing = 0;
16211603
};
1622-
8BA975511D77E2C900601D70 /* Resources */ = {
1623-
isa = PBXResourcesBuildPhase;
1624-
buildActionMask = 2147483647;
1625-
files = (
1626-
);
1627-
runOnlyForDeploymentPostprocessing = 0;
1628-
};
16291604
8BB66A0E1E450DFB00A8F241 /* Resources */ = {
16301605
isa = PBXResourcesBuildPhase;
16311606
buildActionMask = 2147483647;
@@ -1667,13 +1642,6 @@
16671642
);
16681643
runOnlyForDeploymentPostprocessing = 0;
16691644
};
1670-
8BFF17681DF5B4AD005DE734 /* Resources */ = {
1671-
isa = PBXResourcesBuildPhase;
1672-
buildActionMask = 2147483647;
1673-
files = (
1674-
);
1675-
runOnlyForDeploymentPostprocessing = 0;
1676-
};
16771645
/* End PBXResourcesBuildPhase section */
16781646

16791647
/* Begin PBXSourcesBuildPhase section */

TwitterImagePipeline.xcodeproj/xcshareddata/xcschemes/TwitterImagePipeline.framework.xcscheme

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,6 @@
2020
ReferencedContainer = "container:TwitterImagePipeline.xcodeproj">
2121
</BuildableReference>
2222
</BuildActionEntry>
23-
<BuildActionEntry
24-
buildForTesting = "YES"
25-
buildForRunning = "NO"
26-
buildForProfiling = "NO"
27-
buildForArchiving = "NO"
28-
buildForAnalyzing = "YES">
29-
<BuildableReference
30-
BuildableIdentifier = "primary"
31-
BlueprintIdentifier = "8BA975521D77E2C900601D70"
32-
BuildableName = "TIPTests.framework"
33-
BlueprintName = "TIPTests"
34-
ReferencedContainer = "container:TwitterImagePipeline.xcodeproj">
35-
</BuildableReference>
36-
</BuildActionEntry>
3723
<BuildActionEntry
3824
buildForTesting = "YES"
3925
buildForRunning = "NO"

TwitterImagePipeline/Project/NSDictionary+TIPAdditions.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,9 @@ - (void)tip_setObject:(id)object forCaseInsensitiveKey:(NSString *)key
8888
{
8989
TIPAssert(key);
9090
[self tip_removeObjectsForCaseInsensitiveKey:key];
91+
#ifndef __clang_analyzer__ // reports key can be nil nil; we prefer to crash if it is
9192
self[key] = object;
93+
#endif
9294
}
9395

9496
- (void)tip_makeAllKeysLowercase

TwitterImagePipeline/Project/TIPImageDiskCache.m

Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ - (TIPLRUCache *)manifest
213213
}
214214

215215
TIPAssert(manifest != nil);
216-
return manifest;
216+
return (TIPLRUCache * _Nonnull)manifest; // TIPAssert() performed 1 line above
217217
}
218218

219219
- (NSUInteger)totalCost
@@ -1022,38 +1022,46 @@ static void _diskCache_updateImageEntry(SELF_ARG,
10221022
didChangeComplete = YES;
10231023
}
10241024

1025-
// Update xattrs and LRU
1026-
const NSUInteger newCost = existingEntry.partialFileSize + existingEntry.completeFileSize;
1027-
_diskCache_updateByteCounts(self, newCost /*bytesAdded*/, oldCost /*bytesRemoved*/);
1028-
if (!hasPreviousEntry && existingEntry) {
1029-
self->_globalConfig.internalTotalCountForAllDiskCaches += 1;
1030-
}
1025+
if (!existingEntry.partialImageContext && !existingEntry.completeImageContext) {
1026+
// shoot... the save cannot complete -- purge the entry
1027+
if (hasPreviousEntry) {
1028+
[manifest removeEntry:existingEntry];
1029+
}
1030+
} else {
10311031

1032-
if (gTwitterImagePipelineAssertEnabled) {
1033-
if (existingEntry.partialImageContext && 0 == existingEntry.partialFileSize) {
1034-
NSDictionary *info = @{
1035-
@"dimension" : NSStringFromCGSize(existingEntry.partialImageContext.dimensions),
1036-
@"URL" : existingEntry.partialImageContext.URL,
1037-
@"id" : existingEntry.identifier,
1038-
};
1039-
TIPLogError(@"Cached zero cost partial image to disk cache %@", info);
1032+
// Update xattrs and LRU
1033+
const NSUInteger newCost = existingEntry.partialFileSize + existingEntry.completeFileSize;
1034+
_diskCache_updateByteCounts(self, newCost /*bytesAdded*/, oldCost /*bytesRemoved*/);
1035+
if (!hasPreviousEntry && existingEntry) {
1036+
self->_globalConfig.internalTotalCountForAllDiskCaches += 1;
10401037
}
1041-
if (existingEntry.completeImageContext && 0 == existingEntry.completeFileSize) {
1042-
NSDictionary *info = @{
1043-
@"dimension" : NSStringFromCGSize(existingEntry.completeImageContext.dimensions),
1044-
@"URL" : existingEntry.completeImageContext.URL,
1045-
@"id" : existingEntry.identifier,
1046-
};
1047-
TIPLogError(@"Cached zero cost complete image to disk cache %@", info);
1038+
1039+
[manifest addEntry:existingEntry];
1040+
if (didChangePartial) {
1041+
_diskCache_touchEntry(self, existingEntry, forciblyReplaceExisting /*forced*/, YES /*partial*/);
1042+
}
1043+
if (didChangeComplete) {
1044+
_diskCache_touchEntry(self, existingEntry, forciblyReplaceExisting /*forced*/, NO /*partial*/);
10481045
}
1049-
}
10501046

1051-
[manifest addEntry:existingEntry];
1052-
if (didChangePartial) {
1053-
_diskCache_touchEntry(self, existingEntry, forciblyReplaceExisting /*forced*/, YES /*partial*/);
1054-
}
1055-
if (didChangeComplete) {
1056-
_diskCache_touchEntry(self, existingEntry, forciblyReplaceExisting /*forced*/, NO /*partial*/);
1047+
if (gTwitterImagePipelineAssertEnabled) {
1048+
if (existingEntry.partialImageContext && 0 == existingEntry.partialFileSize) {
1049+
NSDictionary *info = @{
1050+
@"dimension" : NSStringFromCGSize(existingEntry.partialImageContext.dimensions),
1051+
@"URL" : existingEntry.partialImageContext.URL,
1052+
@"id" : existingEntry.identifier,
1053+
};
1054+
TIPLogError(@"Cached zero cost partial image to disk cache %@", info);
1055+
}
1056+
if (existingEntry.completeImageContext && 0 == existingEntry.completeFileSize) {
1057+
NSDictionary *info = @{
1058+
@"dimension" : NSStringFromCGSize(existingEntry.completeImageContext.dimensions),
1059+
@"URL" : existingEntry.completeImageContext.URL,
1060+
@"id" : existingEntry.identifier,
1061+
};
1062+
TIPLogError(@"Cached zero cost complete image to disk cache %@", info);
1063+
}
1064+
}
10571065
}
10581066

10591067
[self->_globalConfig pruneAllCachesOfType:self.cacheType withPriorityCache:self];

TwitterImagePipeline/Project/TIPImageRenderedCache.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,9 @@ - (void)inspect:(TIPInspectableCacheCallback)callback
282282
class:[TIPImagePipelineInspectionResultRenderedEntry class]];
283283
TIPAssert(entry != nil);
284284
entry.bytesUsed = [entry.image tip_estimatedSizeInBytes];
285+
#ifndef __clang_analyzer__ // reports entry can be nil; we prefer to crash if it is
285286
[inspectedEntries addObject:entry];
287+
#endif
286288
}
287289
}
288290

TwitterImagePipeline/Project/TIPImageStoreAndMoveOperations.m

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ @interface TIPImageStoreOperation (Private)
4040
static TIPImageContainer * __nullable _getImageContainer(PRIVATE_SELF(TIPImageStoreOperation));
4141
static TIPCompleteImageEntryContext *_getEntryContext(PRIVATE_SELF(TIPImageStoreOperation),
4242
NSURL *imageURL,
43-
TIPImageContainer * __nullable imageContainer);
43+
TIPImageContainer * __nullable imageContainer,
44+
NSString * __nullable imageFilePath,
45+
NSData * __nullable imageData);
4446
static void _asyncStoreMemoryEntry(PRIVATE_SELF(TIPImageStoreOperation),
4547
TIPImageCacheEntry *memoryEntry,
4648
void(^complete)(BOOL));
@@ -193,7 +195,11 @@ - (void)main
193195
NSString *identifier = TIPImageStoreRequestGetImageIdentifier(_request);
194196

195197
// Create context
196-
TIPCompleteImageEntryContext *context = _getEntryContext(self, imageURL, imageContainer);
198+
TIPCompleteImageEntryContext *context = _getEntryContext(self,
199+
imageURL,
200+
imageContainer,
201+
imageFilePath,
202+
imageData);
197203

198204
// Create Memory Entry
199205
TIPImageCacheEntry *memoryEntry = nil;
@@ -330,7 +336,9 @@ @implementation TIPImageStoreOperation (Private)
330336

331337
static TIPCompleteImageEntryContext *_getEntryContext(PRIVATE_SELF(TIPImageStoreOperation),
332338
NSURL *imageURL,
333-
TIPImageContainer * __nullable imageContainer)
339+
TIPImageContainer * __nullable imageContainer,
340+
NSString * __nullable imageFilePath,
341+
NSData * __nullable imageData)
334342
{
335343
TIPAssert(self);
336344
if (!self) {
@@ -354,6 +362,10 @@ @implementation TIPImageStoreOperation (Private)
354362
context.dimensions = imageContainer.dimensions;
355363
} else if ([self->_request respondsToSelector:@selector(imageDimensions)]) {
356364
context.dimensions = self->_request.imageDimensions;
365+
} else if (imageData) {
366+
context.dimensions = TIPDetectImageDataDimensions(imageData);
367+
} else if (imageFilePath) {
368+
context.dimensions = TIPDetectImageFileDimensions(imageFilePath);
357369
}
358370
if ([self->_request respondsToSelector:@selector(imageType)]) {
359371
context.imageType = [self->_request imageType];

TwitterImagePipeline/Project/TIPLRUCache.m

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,22 @@ - (void)addEntry:(id<TIPLRUEntry>)entry
8686

8787
NSString *identifier = entry.LRUEntryIdentifier;
8888
TIPAssert(identifier != nil);
89+
#ifndef __clang_analyzer__
90+
// clang analyzer reports identifier can be nil for the check if (... && _cache[identifier]) {
91+
// just below. (and then, if we ignore only that with #ifndef __clang_analyzer__, then it reports
92+
// _cache[identifier] within the TIPAssert() protected by the if stmt.)
93+
// however, in real life, the TIPAssert(identifier != nil) just above will prevent control from getting to
94+
// the if stmt at all when gTwitterImagePipelineAssertEnabled is true, and when it is false, then the 2nd
95+
// part of the condition (and the stmts protected by the condition) will never be executed and won't crash.
8996
if (gTwitterImagePipelineAssertEnabled && _cache[identifier]) {
9097
TIPAssert((id)_cache[identifier] == (id)entry);
9198
}
99+
#endif
92100

93101
[self moveEntryToFront:entry];
102+
#ifndef __clang_analyzer__ // reports identifier can be nil; we prefer to crash if it is
94103
_cache[identifier] = entry;
104+
#endif
95105

96106
TIPLRUCacheAssertHeadAndTail(self);
97107
}
@@ -114,7 +124,9 @@ - (void)appendEntry:(id<TIPLRUEntry>)entry
114124
entry.previousLRUEntry = _tailEntry;
115125
entry.nextLRUEntry = nil;
116126
_tailEntry = entry;
127+
#ifndef __clang_analyzer__ // reports identifier can be nil; we prefer to crash if it is
117128
_cache[identifier] = entry;
129+
#endif
118130

119131
if (!_headEntry) {
120132
_headEntry = _tailEntry;

TwitterImagePipeline/Project/TIP_Project.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ CGSize TIPScaleToFitKeepingAspectRatio(CGSize sourceSize, CGSize targetSize, CGF
145145
TIPAssert(safe != 0);
146146
NSString *raw = TIPURLDecodeString(safe, NO);
147147
TIPAssert(raw != 0);
148-
return raw;
148+
return (NSString * _Nonnull)raw; // TIPAssert() performed 1 line above
149149
}
150150

151151
dispatch_block_t __nullable TIPStartBackgroundTask(NSString * __nullable name)

0 commit comments

Comments
 (0)