summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gyp/platform-ios.gypi2
-rw-r--r--platform/ios/MGLFileCache.h10
-rw-r--r--platform/ios/MGLFileCache.mm83
-rw-r--r--platform/ios/MGLMapView.mm23
4 files changed, 99 insertions, 19 deletions
diff --git a/gyp/platform-ios.gypi b/gyp/platform-ios.gypi
index 8d42069572..f1f95d908e 100644
--- a/gyp/platform-ios.gypi
+++ b/gyp/platform-ios.gypi
@@ -22,6 +22,8 @@
'../include/mbgl/ios/MGLMapView.h',
'../include/mbgl/ios/MGLMapView+IBAdditions.h',
'../platform/ios/MGLMapView.mm',
+ '../platform/ios/MGLFileCache.h',
+ '../platform/ios/MGLFileCache.mm',
'../include/mbgl/ios/MGLAnnotation.h',
'../include/mbgl/ios/MGLUserLocation.h',
'../platform/ios/MGLUserLocation_Private.h',
diff --git a/platform/ios/MGLFileCache.h b/platform/ios/MGLFileCache.h
new file mode 100644
index 0000000000..5e9f37fe2d
--- /dev/null
+++ b/platform/ios/MGLFileCache.h
@@ -0,0 +1,10 @@
+#import <Foundation/Foundation.h>
+
+#include <mbgl/storage/sqlite_cache.hpp>
+
+@interface MGLFileCache : NSObject
+
++ (mbgl::SQLiteCache *)obtainSharedCacheWithObject:(NSObject *)object;
++ (void)releaseSharedCacheForObject:(NSObject *)object;
+
+@end
diff --git a/platform/ios/MGLFileCache.mm b/platform/ios/MGLFileCache.mm
new file mode 100644
index 0000000000..3303b395f9
--- /dev/null
+++ b/platform/ios/MGLFileCache.mm
@@ -0,0 +1,83 @@
+#import "MGLFileCache.h"
+
+@interface MGLFileCache ()
+
+@property (nonatomic) MGLFileCache *sharedInstance;
+@property (nonatomic) mbgl::SQLiteCache *sharedCache;
+@property (nonatomic) NSHashTable *retainers;
+
+@end
+
+@implementation MGLFileCache
+
+const std::string &defaultCacheDatabasePath() {
+ static const std::string path = []() -> std::string {
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
+ if ([paths count] == 0) {
+ // Disable the cache if we don't have a location to write.
+ return "";
+ }
+
+ NSString *libraryDirectory = [paths objectAtIndex:0];
+ return [[libraryDirectory stringByAppendingPathComponent:@"cache.db"] UTF8String];
+ }();
+ return path;
+}
+
+- (instancetype)init {
+ self = [super init];
+ if (self) {
+ _retainers = [NSHashTable weakObjectsHashTable];
+ }
+ return self;
+}
+
++ (instancetype)sharedInstance {
+ static dispatch_once_t onceToken;
+ static MGLFileCache *_sharedInstance;
+ dispatch_once(&onceToken, ^{
+ _sharedInstance = [[self alloc] init];
+ });
+ return _sharedInstance;
+}
+
+- (void)teardown {
+ if (self.sharedCache) {
+ delete self.sharedCache;
+ self.sharedCache = nullptr;
+ }
+}
+
+- (void)dealloc {
+ [self.retainers removeAllObjects];
+ [self teardown];
+}
+
++ (mbgl::SQLiteCache *)obtainSharedCacheWithObject:(NSObject *)object {
+ return [[MGLFileCache sharedInstance] obtainSharedCacheWithObject:object];
+}
+
+- (mbgl::SQLiteCache *)obtainSharedCacheWithObject:(NSObject *)object {
+ assert([[NSThread currentThread] isMainThread]);
+ if (!self.sharedCache) {
+ self.sharedCache = new mbgl::SQLiteCache(defaultCacheDatabasePath());
+ }
+ [self.retainers addObject:object];
+ return self.sharedCache;
+}
+
++ (void)releaseSharedCacheForObject:(NSObject *)object {
+ return [[MGLFileCache sharedInstance] releaseSharedCacheForObject:object];
+}
+
+- (void)releaseSharedCacheForObject:(NSObject *)object {
+ assert([[NSThread currentThread] isMainThread]);
+ if ([self.retainers containsObject:object]) {
+ [self.retainers removeObject:object];
+ }
+ if ([self.retainers count] == 0) {
+ [self teardown];
+ }
+}
+
+@end
diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm
index 5693c31705..3541dd9a40 100644
--- a/platform/ios/MGLMapView.mm
+++ b/platform/ios/MGLMapView.mm
@@ -11,7 +11,6 @@
#include <mbgl/platform/platform.hpp>
#include <mbgl/platform/darwin/reachability.h>
#include <mbgl/storage/default_file_source.hpp>
-#include <mbgl/storage/sqlite_cache.hpp>
#include <mbgl/storage/network_status.hpp>
#include <mbgl/util/geo.hpp>
#include <mbgl/util/constants.hpp>
@@ -24,6 +23,7 @@
#import "MGLAnnotation.h"
#import "MGLUserLocationAnnotationView.h"
#import "MGLUserLocation_Private.h"
+#import "MGLFileCache.h"
#import "SMCalloutView.h"
@@ -33,21 +33,6 @@
class MBGLView;
-// Returns the path to the default cache database on this system.
-const std::string &defaultCacheDatabase() {
- static const std::string path = []() -> std::string {
- NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
- if ([paths count] == 0) {
- // Disable the cache if we don't have a location to write.
- return "";
- }
-
- NSString *libraryDirectory = [paths objectAtIndex:0];
- return [[libraryDirectory stringByAppendingPathComponent:@"cache.db"] UTF8String];
- }();
- return path;
-}
-
static dispatch_once_t loadGLExtensions;
NSString *const MGLDefaultStyleName = @"mapbox-streets";
@@ -101,7 +86,6 @@ static NSURL *MGLURLForBundledStyleNamed(NSString *styleName)
{
mbgl::Map *_mbglMap;
MBGLView *_mbglView;
- mbgl::SQLiteCache *_mbglFileCache;
mbgl::DefaultFileSource *_mbglFileSource;
BOOL _isTargetingInterfaceBuilder;
@@ -277,8 +261,7 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
// setup mbgl map
//
_mbglView = new MBGLView(self);
- _mbglFileCache = new mbgl::SQLiteCache(defaultCacheDatabase());
- _mbglFileSource = new mbgl::DefaultFileSource(_mbglFileCache);
+ _mbglFileSource = new mbgl::DefaultFileSource([MGLFileCache obtainSharedCacheWithObject:self]);
// Start paused on the IB canvas
_mbglMap = new mbgl::Map(*_mbglView, *_mbglFileSource, mbgl::MapMode::Continuous, _isTargetingInterfaceBuilder);
@@ -424,6 +407,8 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
_mbglFileSource = nullptr;
}
+ [MGLFileCache releaseSharedCacheForObject:self];
+
if (_mbglView)
{
delete _mbglView;