-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Texture's ASImageNode using 6x more memory to display large image than UIImageView #1529
Comments
@christianselig Hey - would be interesting to see if this one could maybe help you: #1469. It's on master only yet, but if you would point to that. Also if you run it within Instruments what is taking up the memory? |
@maicki I assume it's not implicitly activated, right? (It's an experimental feature, |
@christianselig Do something like that in your AppDelegate:
|
@maicki Sorry I'm still a little lost and trying to put this into Swift, is that just a category on EDIT: Just a sec actually I'll just rewrite this in Objective-C haha, my Objective-C to Swift conversion isn't the best. |
Okay, pointed my Podfile to the master branch, rewrote it in Objective-C (see below) and added that code to the AppDelegate. The result was the same, crashed with the following message:
Whereas the UIKit version worked. Objective-C version: #import "ViewController.h"
#import "AsyncDisplayKit/AsyncDisplayKit.h"
#import "PINRemoteImage/PINRemoteImage.h"
@interface ViewController ()
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) ASImageNode *imageNode;
@property (nonatomic, strong) UIImageView *imageView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.scrollView = [[UIScrollView alloc] init];
self.scrollView.frame = self.view.bounds;
self.scrollView.backgroundColor = [UIColor blackColor];
self.scrollView.delegate = self;
[self.view addSubview:self.scrollView];
NSURL *url = [NSURL URLWithString:@"https://preview.redd.it/jlwba6iohkt21.jpg?auto=webp&s=2da20d8e4e24fbbd654a3c002de93d8521062648"];
CGSize imageSize = CGSizeMake(12283.0, 12283.0);
[[[ASPINRemoteImageDownloader sharedDownloader] sharedPINRemoteImageManager] downloadImageWithURL:url options:PINRemoteImageManagerDownloadOptionsSkipDecode completion:^(PINRemoteImageManagerResult * _Nonnull result) {
NSLog(@"Download complete!");
if (!result.image) {
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
// Toggle this if you want to use UIKit instead of AsyncDisplayKit
BOOL useAsyncDisplayKit = YES;
if (useAsyncDisplayKit) {
ASImageNode *imageNode = [[ASImageNode alloc] init];
imageNode.frame = CGRectMake(0.0, 0.0, imageSize.width, imageSize.height);
imageNode.image = result.image;
self.imageNode = imageNode;
[self.scrollView addSubview:imageNode.view];
} else {
UIImageView *imageView = [[UIImageView alloc] init];
imageView.frame = CGRectMake(0.0, 0.0, imageSize.width, imageSize.height);
imageView.image = result.image;
self.imageView = imageView;
[self.scrollView addSubview:imageView];
}
CGFloat scaleToFit = fminf(self.scrollView.bounds.size.width / imageSize.width, self.scrollView.bounds.size.height / imageSize.height);
self.scrollView.contentSize = imageSize;
self.scrollView.minimumZoomScale = scaleToFit;
self.scrollView.maximumZoomScale = 1.0;
self.scrollView.zoomScale = scaleToFit;
});
}];
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
if (self.imageNode) {
return self.imageNode.view;
}
return self.imageView;
}
@end And the AppDelegate.m: #import "AppDelegate.h"
#import "AsyncDisplayKit/AsyncDisplayKit.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
return YES;
}
@end
@implementation ASConfiguration (UserProvided)
+ (ASConfiguration *)textureConfiguration {
ASConfiguration *cfg = [[ASConfiguration alloc] init];
cfg.experimentalFeatures |= ASExperimentalDrawingGlobal;
return cfg;
}
@end I profiled it in Instruments in both the Swift version (without the experimental feature) and the Objective-C version with the experimental feature and both seemed the same with Full Swift (non-experiment) call stack/memory used: Full Objective-C (experiment) stack: |
I have 10000 records, the memory was 40M if I didn't add |
Using Texture 2.8.1. (Also mentioned in Slack)
I’m having a heck of a time figuring out how to get Texture (specifically
ASImageNode
) to work well with a very large image download. Specifically this image from Reddit.I haven’t had any trouble with UIKit (
UIImageView
) which uses 250MB of RAM to render the image, but Texture peaks at about 1.5GB before levelling back down to around 20MB. Unfortunately this means it crashes most devices due to excessive memory usage, and even my iPhone X gets multiple memory warnings (though it doesn't crash).The image is being shown in a
UIScrollView
and the image is about 6MB and 12,000 x 12,000. I created a sample project with just a small bit of code that maps the UIKit implementation to Texture. (Note the scroll view isn't inherently necessary and the issue is visible without it.)I'm sure I'm just doing something silly, and to be fair I'm not understating the complex nature of image rendering! I've just found in the past Texture always performs very favorably to UIKit so something seemed odd. It might be possible that
UIImageView
loads the image into memory only in visible tiles?Code:
Sample Project: LargeImageTextureTest.zip
The text was updated successfully, but these errors were encountered: