• Stars
    star
    277
  • Rank 148,839 (Top 3 %)
  • Language
    Objective-C
  • License
    MIT License
  • Created almost 12 years ago
  • Updated about 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Helper class that allows you to draw views (a)synchronously to a UIImage with caching for great performance.

MSCachedAsyncViewDrawing

Helper class that allows you to draw views (a)synchronously to a UIImage with caching for great performance.

Description

(This assumes you know a bit about CoreGraphics and how some things like blending work. If not, go read this post in the Twitter Engineering Blog).

So you have a UITableView in your application that scrolls slow. You decide to implement the cell drawing entirely in CoreGraphics implementing -[UIView drawRect:] in your cell. This is perfect, until you have to draw images. CGContextDrawImage is really slow compared to using UIImageView.

For this reason, many times you'll find yourself preferring to use UIImageView even if some compositing has to happen on the cell, because rendering images with it is FAST due to the crazy optimizations that it implements internally.

But sometimes you do have to use CGContextDrawImage, because you have to do something more complex like masking, clipping, etc. Wouldn't it be great if you could still do that, but pass the result to a UIImageView easily, so that you get the benefit from both worlds? That's what MSCachedAsyncViewDrawing does.

When to use MSCachedAsyncViewDrawing

Needless to say you shouldn't just go ahead and apply this to all of the UIViews in your app. There's a drawback in this approach, as you're incurring in higher memory usage by storing the result of the all the drawing operations. The only way to know if using MSCachedAsyncViewDrawing improves or not the performance in your particular case, is to try it out and compare. As a general rule on when it makes sense to use it would be when -drawRect: is becoming a bottleneck, specially if it's using CGContextDrawImage inside. This can happen when you have many complex views in the cells of a UITableView.

Sample Project

The sample project contains two view controllers that contain a table view in which every row has 3 views that implement -drawInRect:. One of them uses MSCachedAsyncViewDrawing and the other one doesn't. This is an example on how to use this class and its performance benefit. Install the sample app on your iOS device and compare. It's also a typical use case for this class, since there are many views on screen at the same time, and they all have to render a UIImage, this becomes a bottleneck. MSCachedAsyncViewDrawing makes this asynchronous, hence not blocking the main thread and getting perfect scrolling performance, and it also prevents the views from rendering more than once.

How to use it

  • Install using cocoapods by adding pod 'MSCachedAsyncViewDrawing', '~> 1.0.1' to your Podfile.
  • Or add the MSCachedAsyncViewDrawing.(h+m) files to your project.

This is the main method in MSCachedAsyncViewDrawing:

- (void)drawViewAsyncWithCacheKey:(NSString *)cacheKey
                             size:(CGSize)imageSize
                  backgroundColor:(UIColor *)backgroundColor
                        drawBlock:(MSCachedAsyncViewDrawingDrawBlock)drawBlock
                  completionBlock:(MSCachedAsyncViewDrawingCompletionBlock)completionBlock;

The block types are declared like this:

typedef void (^MSCachedAsyncViewDrawingDrawBlock)(CGRect frame);
typedef void (^MSCachedAsyncViewDrawingCompletionBlock)(UIImage *drawnImage);

MSCachedAsyncViewDrawing is going to take the drawBlock and call it on a background thread, passing it the CGRect that you can pass to a -drawRect: method of a view. When it's done, it's going to cache the UIImage object with the specified cacheKey and call your completionBlock with it.

A subsequent call with the same cacheKey will result in the immediate call of the completionBlock without calling the drawBlock because it'll grab the rendered image from the cache.

The cache is implemented using NSCache, so you don't have to worry about putting caching too many images, because iOS is going to take care of evicting obejcts as the available memory goes low.

If you prefer to block the UI while the rendering is happening, because you want to make sure that the image view is not empty at any point, you can use this other method, which immediately returns the UIImage object:

- (UIImage *)drawViewSyncWithCacheKey:(NSString *)cacheKey
                                 size:(CGSize)imageSize
                      backgroundColor:(UIColor *)backgroundColor
                            drawBlock:(MSCachedAsyncViewDrawingDrawBlock)drawBlock;

Compatibility

  • MSCachedAsyncViewDrawing is compatible with iOS5.0+.
  • MSCachedAsyncViewDrawing uses ARC. To use in a non-ARC project, mark MSCachedAsyncViewDrawing.m with the linker flag -fobjc-arc.

License

MSCachedAsyncViewDrawing is available under the MIT license. See the LICENSE file for more info.

More Repositories

1

MSWeakTimer

Thread-safe NSTimer alternative that doesn't retain the target and supports being used with GCD queues.
Objective-C
971
star
2

MSLeakHunter

Series of tools to help you find and debug objects that are leaking / over-released in your iOS apps.
Objective-C
366
star
3

MSVCLeakHunter

Simple and easy tool to discover View Controllers that are not being deallocated when you expect them to.
Objective-C
116
star
4

MSPageViewController

Create UIPageViewControllers using only storyboards
Objective-C
89
star
5

MSActiveConfig

Remote configuration and A/B Testing framework for iOS
Objective-C
79
star
6

Zinc

Asset distribution system for mobile clients.
Python
40
star
7

MSEmojiChecksumCalculator

Calculate checksums that are human readable and fun!
Objective-C
29
star
8

MSSidebarController

Fully customizable sidebar controller
Objective-C
27
star
9

MSSpec

Kiwi Spec with support to inject mocks using Objection
Objective-C
22
star
10

Zinc-ObjC

Objective-C client for Zinc asset distribution system
Objective-C
17
star
11

provtool

Command line utility for working with Provisioning Profiles
Python
12
star
12

UIImage-MSImageNamed568hSupport

Method for UIImage to be able to load images with the -568h prefix on the iPhone5.
Objective-C
12
star
13

django-versionfield

A DB Independent Custom Field for storing Version numbers for fast indexing
Python
8
star
14

MSWeakMutableSet

Behaves exactly like an NSMutableSet, but doesn't retain the objects.
Objective-C
8
star
15

penmanship

A simple Gradle plug-in that makes it easy to convert Markdown documents into native Android layout XML files.
Java
7
star
16

JavaZinc

Zinc client in Java
Java
6
star
17

pngnq-mac

Mac OSX build of the pngnq image quantizer with some command line modifications
C
5
star
18

iso8601parser

This is a "fork" of https://github.com/square/iso8601parser but the source has disappeared
Objective-C
3
star
19

django-piston

This is my fork of django-piston by jespern that fixes the following bugs: #171, #84, #169
Python
1
star
20

mindsnacks.github.com

1
star