Skip to content

Commit cedc32d

Browse files
author
Mallory Paine
committed
Attempt to fix unreproducible crasher by replacing NSMapTable with our own weak reference collection.
1 parent d3af631 commit cedc32d

4 files changed

Lines changed: 59 additions & 5 deletions

File tree

FastImageCache/FICImageTable.m

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#import "FICImageTableChunk.h"
1313
#import "FICImageTableEntry.h"
1414
#import "FICUtilities.h"
15+
#import "FICWeakReference.h"
1516

1617
#import "FICImageCache+FICErrorLogging.h"
1718

@@ -49,7 +50,7 @@ @interface FICImageTable () {
4950
size_t _chunkLength;
5051
NSInteger _chunkCount;
5152

52-
NSMapTable *_chunkMapTable;
53+
NSMutableDictionary *_chunkDictionary;
5354
NSMutableArray *_recentChunks;
5455
NSRecursiveLock *_lock;
5556

@@ -137,7 +138,7 @@ - (instancetype)initWithFormat:(FICImageFormat *)imageFormat {
137138
_imageRowLength = (NSInteger)FICByteAlignForCoreAnimation(pixelSize.width * bytesPerPixel);
138139
_imageLength = _imageRowLength * (NSInteger)pixelSize.height;
139140

140-
_chunkMapTable = [NSMapTable mapTableWithKeyOptions:NSMapTableStrongMemory valueOptions:NSMapTableWeakMemory];
141+
_chunkDictionary = [[NSMutableDictionary alloc] init];
141142

142143
_indexMap = [[NSMutableDictionary alloc] init];
143144
_occupiedIndexes = [[NSMutableIndexSet alloc] init];
@@ -198,16 +199,26 @@ - (void)dealloc {
198199
#pragma mark - Working with Chunks
199200

200201
- (FICImageTableChunk *)_cachedChunkAtIndex:(NSInteger)index {
201-
FICImageTableChunk *cachedChunk = [_chunkMapTable objectForKey:@(index)];
202+
FICImageTableChunk *cachedChunk = nil;
203+
NSNumber *indexNumber = @(index);
204+
FICWeakReference *chunkReference = [_chunkDictionary objectForKey:indexNumber];
205+
206+
if (chunkReference) {
207+
cachedChunk = [chunkReference object];
208+
if (!cachedChunk) {
209+
[_chunkDictionary removeObjectForKey:indexNumber];
210+
}
211+
}
202212

203213
return cachedChunk;
204214
}
205215

206216
- (void)_setChunk:(FICImageTableChunk *)chunk index:(NSInteger)index {
217+
NSNumber *indexNumber = @(index);
207218
if (chunk != nil) {
208-
[_chunkMapTable setObject:chunk forKey:@(index)];
219+
[_chunkDictionary setObject:[[FICWeakReference alloc] initWithObject:chunk] forKey:indexNumber];
209220
} else {
210-
[_chunkMapTable removeObjectForKey:@(index)];
221+
[_chunkDictionary removeObjectForKey:indexNumber];
211222
}
212223
}
213224

FastImageCache/FICWeakReference.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//
2+
// FICWeakReference.h
3+
// FastImageCache
4+
//
5+
// Copyright (c) 2014 Path, Inc.
6+
// See LICENSE for full license agreement.
7+
//
8+
9+
#import "FICImports.h"
10+
11+
@interface FICWeakReference : NSObject
12+
13+
- (instancetype)initWithObject:(id)object;
14+
15+
@property(nonatomic, weak) id object;
16+
17+
@end

FastImageCache/FICWeakReference.m

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//
2+
// FICWeakReference.m
3+
// FastImageCache
4+
//
5+
// Copyright (c) 2014 Path, Inc.
6+
// See LICENSE for full license agreement.
7+
//
8+
9+
#import "FICWeakReference.h"
10+
11+
@implementation FICWeakReference
12+
13+
- (instancetype)initWithObject:(id)object {
14+
if (self = [super init]) {
15+
_object = object;
16+
}
17+
return self;
18+
}
19+
20+
@end

FastImageCacheDemo/FastImageCacheDemo.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
2E1BC90117C57CDF00836A7E /* FICDViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E1BC8FD17C57CD300836A7E /* FICDViewController.m */; };
2121
2E64541017FF24C0001D0531 /* FICDTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E64540F17FF24C0001D0531 /* FICDTableView.m */; };
2222
2EA7994417B2A10200684B86 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2EA7993F17B2A10200684B86 /* main.m */; };
23+
31F9BA0418822719009630D0 /* FICWeakReference.m in Sources */ = {isa = PBXBuildFile; fileRef = 31F9BA0318822719009630D0 /* FICWeakReference.m */; };
2324
EB171332181F089F00EB0E24 /* CoreImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EB171331181F089F00EB0E24 /* CoreImage.framework */; };
2425
EB642D8017DCB1750013D644 /* FICDFullscreenPhotoDisplayController.m in Sources */ = {isa = PBXBuildFile; fileRef = EB642D7F17DCB1750013D644 /* FICDFullscreenPhotoDisplayController.m */; };
2526
EB6BD53818079DAB00D762CE /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EB6BD53718079DAB00D762CE /* CoreGraphics.framework */; };
@@ -56,6 +57,8 @@
5657
2E64540E17FF24C0001D0531 /* FICDTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FICDTableView.h; sourceTree = "<group>"; };
5758
2E64540F17FF24C0001D0531 /* FICDTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FICDTableView.m; sourceTree = "<group>"; };
5859
2EA7993F17B2A10200684B86 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
60+
31F9BA0218822719009630D0 /* FICWeakReference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FICWeakReference.h; sourceTree = "<group>"; };
61+
31F9BA0318822719009630D0 /* FICWeakReference.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FICWeakReference.m; sourceTree = "<group>"; };
5962
EB171331181F089F00EB0E24 /* CoreImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreImage.framework; path = System/Library/Frameworks/CoreImage.framework; sourceTree = SDKROOT; };
6063
EB642D3717DC9C690013D644 /* FastImageCacheDemo-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "FastImageCacheDemo-Info.plist"; sourceTree = "<group>"; };
6164
EB642D7E17DCB1750013D644 /* FICDFullscreenPhotoDisplayController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FICDFullscreenPhotoDisplayController.h; sourceTree = "<group>"; };
@@ -145,6 +148,8 @@
145148
EB6BD53918079E2D00D762CE /* FICImports.h */,
146149
2E1BC8ED17C57C4700836A7E /* FICUtilities.h */,
147150
2E1BC8EE17C57C4700836A7E /* FICUtilities.m */,
151+
31F9BA0218822719009630D0 /* FICWeakReference.h */,
152+
31F9BA0318822719009630D0 /* FICWeakReference.m */,
148153
);
149154
name = FastImageCache;
150155
path = ../FastImageCache;
@@ -243,6 +248,7 @@
243248
isa = PBXSourcesBuildPhase;
244249
buildActionMask = 2147483647;
245250
files = (
251+
31F9BA0418822719009630D0 /* FICWeakReference.m in Sources */,
246252
2EA7994417B2A10200684B86 /* main.m in Sources */,
247253
2E1BC8F017C57C4700836A7E /* FICImageCache.m in Sources */,
248254
2E1BC8F117C57C4700836A7E /* FICImageFormat.m in Sources */,

0 commit comments

Comments
 (0)