From 5173dd2114c7f7c180a23911f2a94855fd350813 Mon Sep 17 00:00:00 2001
From: Jidong Chen <jidongchen93@gmail.com>
Date: Tue, 11 Jun 2019 20:12:02 +0800
Subject: [PATCH] update

---
 ios/Classes/1.0/FLBFactory.m                  |   1 +
 ios/Classes/1.0/FLBFlutterEngine.m            |  93 --------
 ios/Classes/1.0/FLBFlutterEngineOld.m         |   4 -
 ios/Classes/1.0/FLBFlutterProvider.h          |   4 +-
 ios/Classes/1.0/FLBViewProviderFactory.m      |   8 -
 ios/Classes/1.0/Support/Cache/FLBStackCache.h |  72 ++++++
 ios/Classes/1.0/Support/Cache/FLBStackCache.m | 210 ++++++++++++++++++
 .../Cache/FLBStackCacheObjectImg.h}           |  14 +-
 .../Support/Cache/FLBStackCacheObjectImg.m    | 116 ++++++++++
 .../1.0/Support/Memory/FLBMemoryInspector.h   |  47 ++++
 .../1.0/Support/Memory/FLBMemoryInspector.mm  | 157 +++++++++++++
 11 files changed, 611 insertions(+), 115 deletions(-)
 delete mode 100755 ios/Classes/1.0/FLBFlutterEngine.m
 create mode 100755 ios/Classes/1.0/Support/Cache/FLBStackCache.h
 create mode 100755 ios/Classes/1.0/Support/Cache/FLBStackCache.m
 rename ios/Classes/1.0/{FLBFlutterEngine.h => Support/Cache/FLBStackCacheObjectImg.h} (85%)
 create mode 100755 ios/Classes/1.0/Support/Cache/FLBStackCacheObjectImg.m
 create mode 100755 ios/Classes/1.0/Support/Memory/FLBMemoryInspector.h
 create mode 100755 ios/Classes/1.0/Support/Memory/FLBMemoryInspector.mm

diff --git a/ios/Classes/1.0/FLBFactory.m b/ios/Classes/1.0/FLBFactory.m
index dcdf2f0..c7fb089 100644
--- a/ios/Classes/1.0/FLBFactory.m
+++ b/ios/Classes/1.0/FLBFactory.m
@@ -38,4 +38,5 @@
     return FLBFlutterViewContainer.new;
 }
 
+
 @end
diff --git a/ios/Classes/1.0/FLBFlutterEngine.m b/ios/Classes/1.0/FLBFlutterEngine.m
deleted file mode 100755
index 14ed54a..0000000
--- a/ios/Classes/1.0/FLBFlutterEngine.m
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * The MIT License (MIT)
- * 
- * Copyright (c) 2019 Alibaba Group
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#import "FLBFlutterEngine.h"
-#import <Flutter/Flutter.h>
-#import "FLBFlutterViewControllerAdaptor.h"
-
-#if RELEASE_1_0
-
-@interface FLBFlutterEngine()
-@property (nonatomic,strong) FLBFlutterViewControllerAdaptor *viewController;
-@property (nonatomic,strong) FlutterEngine *engine;
-@end
-
-@implementation FLBFlutterEngine
-
-- (instancetype)init
-{
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
-    
-    if (self = [super init]) {
-        _engine = [[FlutterEngine alloc] initWithName:@"io.flutter" project:nil];
-        [_engine runWithEntrypoint:nil];
-        _viewController = [[FLBFlutterViewControllerAdaptor alloc] initWithEngine:_engine
-                                                                          nibName:nil
-                                                                           bundle:nil];
-        [_viewController view];
-        Class clazz = NSClassFromString(@"GeneratedPluginRegistrant");
-        if (clazz) {
-            if ([clazz respondsToSelector:NSSelectorFromString(@"registerWithRegistry:")]) {
-                [clazz performSelector:NSSelectorFromString(@"registerWithRegistry:")
-                            withObject:_viewController];
-            }
-        }
-    }
-    
-    return self;
-#pragma clang diagnostic pop
-}
-
-- (FlutterViewController *)viewController
-{
-    return _viewController;
-}
-
-- (void)pause
-{
-    //TODO: [[_engine.get() lifecycleChannel] sendMessage:@"AppLifecycleState.paused"];
-    [self.viewController boost_viewWillDisappear:NO];
-    [self.viewController boost_viewDidDisappear:NO];
-}
-
-- (void)resume
-{
-    //TODO:   [[_engine.get() lifecycleChannel] sendMessage:@"AppLifecycleState.resumed"];
-    [self.viewController boost_viewWillAppear:NO];
-    [self.viewController boost_viewDidAppear:NO];
-}
-
-- (void)inactive
-{
-    [[_engine lifecycleChannel] sendMessage:@"AppLifecycleState.inactive"];
-}
-
-- (void)setAccessibilityEnable:(BOOL)enable
-{
-    self.viewController.accessibilityEnable = enable;
-}
-@end
-
-#endif
diff --git a/ios/Classes/1.0/FLBFlutterEngineOld.m b/ios/Classes/1.0/FLBFlutterEngineOld.m
index 3e596d2..6ee57cc 100755
--- a/ios/Classes/1.0/FLBFlutterEngineOld.m
+++ b/ios/Classes/1.0/FLBFlutterEngineOld.m
@@ -100,9 +100,5 @@
     [self.viewController sendOnChannel:channel message:data];
 }
 
-- (void)setAccessibilityEnable:(BOOL)enable
-{
-    self.viewController.accessibilityEnable = enable;
-}
 
 @end
diff --git a/ios/Classes/1.0/FLBFlutterProvider.h b/ios/Classes/1.0/FLBFlutterProvider.h
index a514c49..bb50d05 100755
--- a/ios/Classes/1.0/FLBFlutterProvider.h
+++ b/ios/Classes/1.0/FLBFlutterProvider.h
@@ -34,9 +34,7 @@ NS_ASSUME_NONNULL_BEGIN
 @protocol FLBFlutterProvider <NSObject>
 
 @required
-- (FlutterEngine *)engine;
-- (void)atacheToViewController:(FlutterViewController *)vc;
-- (void)detach;
+
 - (void)pause;
 - (void)resume;
 - (void)inactive;
diff --git a/ios/Classes/1.0/FLBViewProviderFactory.m b/ios/Classes/1.0/FLBViewProviderFactory.m
index 0bd7d26..20c4b67 100755
--- a/ios/Classes/1.0/FLBViewProviderFactory.m
+++ b/ios/Classes/1.0/FLBViewProviderFactory.m
@@ -32,20 +32,12 @@
 
 - (id<FLBFlutterViewProvider>)createViewProviderWithPlatform:(id<FLBPlatform>)platform
 {
-#if RELEASE_1_0
-    return [FLBFlutterEngine new];
-#else
     return [[FLBFlutterEngineOld alloc] initWithPlatform:platform];
-#endif
 }
 
 - (id<FLBFlutterViewProvider>)createViewProvider
 {
-#if RELEASE_1_0
-    return [FLBFlutterEngine new];
-#else
     return [FLBFlutterEngineOld new];
-#endif
 }
 
 @end
diff --git a/ios/Classes/1.0/Support/Cache/FLBStackCache.h b/ios/Classes/1.0/Support/Cache/FLBStackCache.h
new file mode 100755
index 0000000..75c067c
--- /dev/null
+++ b/ios/Classes/1.0/Support/Cache/FLBStackCache.h
@@ -0,0 +1,72 @@
+/*
+ * The MIT License (MIT)
+ * 
+ * Copyright (c) 2019 Alibaba Group
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#import <Foundation/Foundation.h>
+
+@class FLBStackCache;
+
+@protocol FLBStackCacheObject<NSObject>
+
+@required
+@property (nonatomic,copy) NSString *key;
+
+- (BOOL)writeToFileWithKey:(NSString *)key
+                     queue:(dispatch_queue_t)queue
+                     cache:(FLBStackCache *)cache
+                completion:(void (^)(NSError *err,NSString *path))completion;
+
++ (BOOL)loadFromFileWithKey:(NSString *)key
+                      queue:(dispatch_queue_t)queue
+                     cache:(FLBStackCache *)cache
+                 completion:(void (^)(NSError *err ,id<FLBStackCacheObject>))completion;
+
+- (BOOL)removeCachedFileWithKey:(NSString *)key
+                          queue:(dispatch_queue_t)queue
+                          cache:(FLBStackCache *)cache
+                     completion:(void (^)(NSError *, NSString *))completion;
+
+
+@end
+
+
+@interface FLBStackCache : NSObject
++ (instancetype)sharedInstance;
+
+/**
+ * Num of objects allowed in memory.
+ * Default value is set to 2.
+ */
+@property (nonatomic,assign) NSUInteger inMemoryCount;
+
+#pragma mark - basic operations.
+- (void)pushObject:(id<FLBStackCacheObject>)obj key:(NSString *)key;
+- (id<FLBStackCacheObject>)remove:(NSString *)key;
+- (void)invalidate:(NSString *)key;
+- (BOOL)empty;
+- (void)clear;
+- (id<FLBStackCacheObject>)objectForKey:(NSString *)key;
+
+#pragma mark - Disk thing.
+- (NSString *)cacheDir;
+@end
diff --git a/ios/Classes/1.0/Support/Cache/FLBStackCache.m b/ios/Classes/1.0/Support/Cache/FLBStackCache.m
new file mode 100755
index 0000000..3a153d5
--- /dev/null
+++ b/ios/Classes/1.0/Support/Cache/FLBStackCache.m
@@ -0,0 +1,210 @@
+/*
+ * The MIT License (MIT)
+ * 
+ * Copyright (c) 2019 Alibaba Group
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#import "FLBStackCache.h"
+
+@interface FLBStackCache()
+
+@property (nonatomic,strong) NSMutableArray *keyStack;
+@property (nonatomic,strong) NSMutableDictionary *typesMap;
+@property (nonatomic,strong) NSMutableDictionary *inMemoryObjectsMap;
+@property (nonatomic,strong) NSMutableDictionary *loadinMap;
+@property (nonatomic,strong) dispatch_queue_t queueIO;
+@end
+
+@implementation FLBStackCache
+
++ (instancetype)sharedInstance
+{
+    static id sInstance = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        sInstance = [self.class new];
+    });
+    
+    return sInstance;
+}
+
+- (BOOL)empty
+{
+    return _keyStack.count<=0;
+}
+
+- (void)clear
+{
+    [self.keyStack removeAllObjects];
+    [self.inMemoryObjectsMap removeAllObjects];
+    [self.typesMap removeAllObjects];
+    NSError *err = nil;
+    [[NSFileManager defaultManager] removeItemAtPath:self.cacheDir error:&err];
+    if (err) {
+        NSLog(@"fail to remove cache dir %@",err);
+    }
+}
+
+
+- (instancetype)init
+{
+    if (self = [super init]) {
+        _keyStack = [NSMutableArray new];
+        _inMemoryObjectsMap = [NSMutableDictionary new];
+        _loadinMap = [NSMutableDictionary new];
+        _typesMap = [NSMutableDictionary new];
+        _queueIO = dispatch_queue_create("Stack cache working queue", NULL);
+    }
+    _inMemoryCount = 2;
+    return self;
+}
+
+ - (void)pushObject:(id<FLBStackCacheObject>)obj
+                key:(NSString *)key
+{
+    if (!obj || key.length <= 0) {
+        return;
+    }
+    
+    if(![_keyStack containsObject:key]){
+        [_keyStack addObject:key];
+    }else{
+        //return;
+    }
+    
+    obj.key = key;
+    _typesMap[key] = obj.class;
+    _inMemoryObjectsMap[key] = obj;
+
+    for(NSUInteger i = _keyStack.count - _inMemoryObjectsMap.count ;
+        i < _keyStack.count && _inMemoryObjectsMap.count > _inMemoryCount;
+        i++){
+        
+        NSString *keyToSave = _keyStack[i];
+        if(_inMemoryObjectsMap[keyToSave]){
+            id<FLBStackCacheObject> ob = _inMemoryObjectsMap[keyToSave];
+            [_inMemoryObjectsMap removeObjectForKey:keyToSave];
+            [ob writeToFileWithKey:keyToSave
+                             queue:_queueIO
+                             cache:self
+                        completion:^(NSError *err, NSString *path) {
+                            if (err) {
+                                NSLog(@"Caching object to file failed!");
+                            }
+                        }];
+        }
+    }
+}
+
+- (id<FLBStackCacheObject>)objectForKey:(NSString *)key
+{
+    return _inMemoryObjectsMap[key];
+}
+
+- (id<FLBStackCacheObject>)remove:(NSString *)key
+{
+    if([self empty]) return nil;
+    
+    if(![_keyStack containsObject:key]) return nil;
+    
+    id ob = _inMemoryObjectsMap[key];
+    
+    [_keyStack removeObject:key];
+    [_inMemoryObjectsMap removeObjectForKey:key];
+    [_typesMap removeObjectForKey:key];
+
+    [self preloadIfNeeded];
+    
+    return ob;
+}
+
+- (void)invalidate:(NSString *)key
+{
+    if(!key || [self empty]) return;
+    
+    if(![_keyStack containsObject:key]) return;
+    
+    id<FLBStackCacheObject> ob = _inMemoryObjectsMap[key];
+    [ob removeCachedFileWithKey:key
+                          queue:_queueIO
+                          cache:self
+                     completion:^(NSError *err, NSString *k) {
+    }];
+    [_inMemoryObjectsMap removeObjectForKey:key];
+    
+    [self preloadIfNeeded];
+}
+
+- (void)preloadIfNeeded
+{
+    for(NSString *key in self.keyStack.reverseObjectEnumerator){
+        Class typeClass = _typesMap[key];
+        id cache = _inMemoryObjectsMap[key];
+        if(typeClass && !cache && [typeClass conformsToProtocol: @protocol(FLBStackCacheObject)]){
+            _loadinMap[key] = @(YES);
+            [typeClass loadFromFileWithKey:key
+                                     queue:_queueIO
+                                     cache:self
+                                completion:^(NSError *err ,id<FLBStackCacheObject> ob){
+                                    [self.loadinMap removeObjectForKey:key];
+                                    if (ob && !err) {
+                                        if(self.typesMap[key]){
+                                            self.inMemoryObjectsMap[key] = ob;
+                                        }
+                                    }else{
+                                        NSLog(@"preload object from file failed!");
+                                    }
+                                }];
+        }
+
+        if(_inMemoryObjectsMap.count + _loadinMap.count >= _inMemoryCount){
+            break;
+        }
+    }
+}
+
+
+
+- (NSString *)cacheDir
+{
+    static NSString *cachePath = nil;
+    if (!cachePath) {
+        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
+        NSString *cacheDirectory = [paths objectAtIndex:0];
+        cachePath = [cacheDirectory stringByAppendingPathComponent:@"FlutterScreenshots"];
+    }
+    
+    BOOL dir = NO;
+    if(![[NSFileManager defaultManager] fileExistsAtPath:cachePath isDirectory:&dir]){
+        NSError *eror = nil;
+        [[NSFileManager defaultManager] createDirectoryAtPath:cachePath
+                                  withIntermediateDirectories:YES
+                                                   attributes:nil
+                                                        error:&eror];
+        if (eror) {
+            NSLog(@"%@",eror);
+        }
+    }
+    
+    return cachePath;
+}
+
+@end
diff --git a/ios/Classes/1.0/FLBFlutterEngine.h b/ios/Classes/1.0/Support/Cache/FLBStackCacheObjectImg.h
similarity index 85%
rename from ios/Classes/1.0/FLBFlutterEngine.h
rename to ios/Classes/1.0/Support/Cache/FLBStackCacheObjectImg.h
index 85e0851..9ce0dc5 100755
--- a/ios/Classes/1.0/FLBFlutterEngine.h
+++ b/ios/Classes/1.0/Support/Cache/FLBStackCacheObjectImg.h
@@ -23,15 +23,15 @@
  */
 
 #import <Foundation/Foundation.h>
-#import "FLBFlutterViewProvider.h"
 
-NS_ASSUME_NONNULL_BEGIN
+#import "FLBStackCache.h"
 
-#if RELEASE_1_0
+@interface FLBStackCacheObjectImg : NSObject<FLBStackCacheObject>
 
-@interface FLBFlutterEngine : NSObject<FLBFlutterViewProvider>
-@end
+@property (nonatomic,copy) NSString *key;
+
+- (instancetype)initWithImage:(UIImage *)image;
 
-#endif
+- (UIImage *)image;
 
-NS_ASSUME_NONNULL_END
+@end
diff --git a/ios/Classes/1.0/Support/Cache/FLBStackCacheObjectImg.m b/ios/Classes/1.0/Support/Cache/FLBStackCacheObjectImg.m
new file mode 100755
index 0000000..b95eef1
--- /dev/null
+++ b/ios/Classes/1.0/Support/Cache/FLBStackCacheObjectImg.m
@@ -0,0 +1,116 @@
+/*
+ * The MIT License (MIT)
+ * 
+ * Copyright (c) 2019 Alibaba Group
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#import "FLBStackCacheObjectImg.h"
+
+@interface FLBStackCacheObjectImg()
+@property (nonatomic,strong) UIImage *image;
+@end
+
+@implementation FLBStackCacheObjectImg
+
+- (instancetype)initWithImage:(UIImage *)image
+{
+    if (self = [super init]) {
+        _image = image;
+    }
+    
+    return self;
+}
+
+
+
++ (BOOL)loadFromFileWithKey:(NSString *)key
+                      queue:(dispatch_queue_t)queue
+                      cache:(FLBStackCache *)cache
+                 completion:(void (^)(NSError *, id<FLBStackCacheObject>))completion
+{
+    dispatch_async(queue, ^{
+        UIImage *image = [[UIImage alloc] initWithContentsOfFile:[self filePathByKey:key dirPath:cache.cacheDir]];
+        if (completion) {
+            if (image) {
+                FLBStackCacheObjectImg *ob = [[FLBStackCacheObjectImg alloc] initWithImage:image];
+                ob.key = key;
+                completion(nil,ob);
+            }else{
+                completion([NSError new],nil);
+            }
+        }
+    });
+    
+    return YES;
+}
+
++ (NSString *)filePathByKey:(NSString *)key dirPath:(NSString *)cacheDir
+{
+    key = [key stringByReplacingOccurrencesOfString:@"/" withString:@""];
+    key = [key stringByReplacingOccurrencesOfString:@":" withString:@""];
+    NSString *path = [cacheDir stringByAppendingPathComponent:key];
+    return path;
+}
+
+- (BOOL)writeToFileWithKey:(NSString *)key
+                     queue:(dispatch_queue_t)queue
+                     cache:(FLBStackCache *)cache
+                completion:(void (^)(NSError *, NSString *))completion
+{
+    if(!_image){
+        return NO;
+    }
+    
+    dispatch_async(queue, ^{
+        NSData *imgData = UIImagePNGRepresentation(self.image);
+        NSString *filePath = [FLBStackCacheObjectImg filePathByKey:key dirPath:cache.cacheDir];
+        [imgData writeToFile:filePath atomically:YES];
+        if (completion) {
+            completion(nil,key);
+        }
+    });
+    
+    return YES;
+}
+
+- (BOOL)removeCachedFileWithKey:(NSString *)key
+                          queue:(dispatch_queue_t)queue
+                          cache:(FLBStackCache *)cache
+                     completion:(void (^)(NSError *, NSString *))completion
+{
+    if(!key){
+        return NO;
+    }
+    
+    dispatch_async(queue, ^{
+        NSString *filePath = [FLBStackCacheObjectImg filePathByKey:key dirPath:cache.cacheDir];
+        NSError *err = nil;
+        [NSFileManager.defaultManager removeItemAtPath:filePath error:&err];
+        if (completion) {
+            completion(err,key);
+        }
+    });
+    
+    return YES;
+}
+
+
+@end
diff --git a/ios/Classes/1.0/Support/Memory/FLBMemoryInspector.h b/ios/Classes/1.0/Support/Memory/FLBMemoryInspector.h
new file mode 100755
index 0000000..f04b3f4
--- /dev/null
+++ b/ios/Classes/1.0/Support/Memory/FLBMemoryInspector.h
@@ -0,0 +1,47 @@
+/*
+ * The MIT License (MIT)
+ * 
+ * Copyright (c) 2019 Alibaba Group
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#import <Foundation/Foundation.h>
+
+#define kFLBMemoryInspectorChangedNotification @"__FlutterMemoryInspectorChangedNotification__"
+#define kFLBMemoryInspectorKeyCondition @"condition"
+
+typedef NS_ENUM(NSUInteger,FLBMemoryCondition) {
+    FLBMemoryConditionUnknown,
+    FLBMemoryConditionNormal,
+    FLBMemoryConditionLowMemory,
+    FLBMemoryConditionExtremelyLow,
+    FLBMemoryConditionAboutToDie
+};
+
+@interface FLBMemoryInspector : NSObject
+
++ (instancetype)sharedInstance;
+
+- (FLBMemoryCondition)currentCondition;
+- (int64_t)currentFootPrint;
+- (int64_t)deviceMemory;
+- (BOOL)smallMemoryDevice;
+
+@end
diff --git a/ios/Classes/1.0/Support/Memory/FLBMemoryInspector.mm b/ios/Classes/1.0/Support/Memory/FLBMemoryInspector.mm
new file mode 100755
index 0000000..2854b76
--- /dev/null
+++ b/ios/Classes/1.0/Support/Memory/FLBMemoryInspector.mm
@@ -0,0 +1,157 @@
+/*
+ * The MIT License (MIT)
+ * 
+ * Copyright (c) 2019 Alibaba Group
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#import "FLBMemoryInspector.h"
+
+#include <mach/mach.h>
+#include <stdlib.h>
+#include <sys/sysctl.h>
+
+#define MB(_v_) (_v_*1024*1024)
+#define SYSTEM_VERSION_EQUAL_TO(v)                  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
+#define SYSTEM_VERSION_GREATER_THAN(v)              ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
+#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
+#define SYSTEM_VERSION_LESS_THAN(v)                 ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
+#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)
+
+@interface FLBMemoryInspector()
+@property(nonatomic,assign) FLBMemoryCondition condition;
+@end
+
+@implementation FLBMemoryInspector
+
++ (instancetype)sharedInstance
+{
+    static id sInstance = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        sInstance = [[self.class alloc] init];
+    });
+    
+    return sInstance;
+}
+
+static bool isHighterThanIos9(){
+    bool ret = SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"9.0.0");
+    return ret;
+}
+
+static int64_t memoryFootprint()
+{
+    task_vm_info_data_t vmInfo;
+    mach_msg_type_number_t count = TASK_VM_INFO_COUNT;
+    kern_return_t result = task_info(mach_task_self(), TASK_VM_INFO, (task_info_t) &vmInfo, &count);
+    if (result != KERN_SUCCESS)
+        return -1;
+    return vmInfo.phys_footprint;
+}
+
+
+static int64_t _memoryWarningLimit()
+{
+    size_t size;
+    sysctlbyname("hw.machine", NULL, &size, NULL, 0);
+    char *machine =(char *) malloc(size);
+    sysctlbyname("hw.machine", machine, &size, NULL, 0);
+    NSString *platform = [NSString stringWithUTF8String:machine];
+    free(machine);
+
+    if ([platform isEqualToString:@"iPhone5,1"])    return MB(600);
+    if ([platform isEqualToString:@"iPhone5,2"])    return MB(600);
+    if ([platform isEqualToString:@"iPhone5,3"])    return MB(600);
+    if ([platform isEqualToString:@"iPhone5,4"])    return MB(600);
+    if ([platform isEqualToString:@"iPhone6,1"])    return MB(600);
+    if ([platform isEqualToString:@"iPhone6,2"])    return MB(600);
+    if ([platform isEqualToString:@"iPhone7,1"])    return MB(600);
+    if ([platform isEqualToString:@"iPhone7,2"])    return MB(600);
+    if ([platform isEqualToString:@"iPhone8,1"])    return MB(1280);
+    if ([platform isEqualToString:@"iPhone8,2"])    return MB(1280);
+    if ([platform isEqualToString:@"iPhone8,4"])    return MB(1280);
+    if ([platform isEqualToString:@"iPhone9,1"])    return MB(1280);
+    if ([platform isEqualToString:@"iPhone9,2"])    return MB(1950);
+    if ([platform isEqualToString:@"iPhone9,3"])    return MB(1280);
+    if ([platform isEqualToString:@"iPhone9,4"])    return MB(1950);
+    if ([platform isEqualToString:@"iPhone10,1"])   return MB(1280);
+    if ([platform isEqualToString:@"iPhone10,2"])   return MB(1950);
+    if ([platform isEqualToString:@"iPhone10,3"])   return MB(1950);
+    if ([platform isEqualToString:@"iPhone10,4"])   return MB(1280);
+    if ([platform isEqualToString:@"iPhone10,5"])   return MB(1950);
+    if ([platform isEqualToString:@"iPhone10,6"])   return MB(1950);
+    
+    return 0;
+}
+
+static int64_t getLimit(){
+    const static size_t l = _memoryWarningLimit();
+    return l;
+}
+
+- (int64_t)deviceMemory
+{
+    int64_t size = [NSProcessInfo processInfo].physicalMemory;
+    return size;
+}
+
+- (BOOL)smallMemoryDevice
+{
+    if([self deviceMemory] <= MB(1024)){
+        return YES;
+    }else{
+        return NO;
+    }
+}
+
+- (FLBMemoryCondition)currentCondition
+{
+    FLBMemoryCondition newCondition = FLBMemoryConditionUnknown;
+    
+
+    if(!isHighterThanIos9() || getLimit() <= 0){
+        newCondition = FLBMemoryConditionUnknown;
+    }else if(memoryFootprint() < getLimit() * 0.40){
+        newCondition = FLBMemoryConditionNormal;
+    }else if(memoryFootprint() < getLimit() * 0.60){
+        newCondition = FLBMemoryConditionLowMemory;
+    }else if(memoryFootprint() < getLimit() * 0.80){
+        newCondition = FLBMemoryConditionExtremelyLow;
+    }else{
+        newCondition = FLBMemoryConditionAboutToDie;
+    }
+    
+    if (newCondition != self.condition) {
+        [[NSNotificationCenter defaultCenter] postNotificationName:kFLBMemoryInspectorChangedNotification
+                                                            object:@{kFLBMemoryInspectorKeyCondition:@(newCondition)}];
+    }
+    
+    self.condition = newCondition;
+    
+    return newCondition;
+}
+
+- (int64_t)currentFootPrint
+{
+    return memoryFootprint();
+}
+
+@end
-- 
2.26.2