iOS Development: Performance optimization for Mkmapview

Source: Internet
Author: User

The most recently done project is lbs, the main member positioning function, which is our UI design.

At first glance, it looks good. Different people will show different avatars but when people get together, the problem comes.

When there are many people (for example, the picture above), the map slides up and it feels obvious that the discomfort of the card can torture the dead, so naturally we to solve this problem (wait, don't spit it out. Why not use map aggregation because this is already the map to the maximum aggregation is not suitable for this issue discussion)

Analysis

First look at how I realized this annotationview because this annotationsview is alien (that is, can not be set by the rounded corners directly to get) and the picture inside also because of users and different so the solution is to use Layer.mask to mask the code as follows

@implementation Mmannotationview

-(Instancetype) Initwithannotation: (id) annotation Reuseidentifier: (NSString *) reuseidentifier

{

self = [super initwithannotation:annotation reuseidentifier:reuseidentifier];

if (self)

{

Self.frame = CGRectMake (0, 0, track_annotation_size.width, track_annotation_size.height);

Self.centeroffset = Cgpointmake (0,-(track_annotation_size.height-3)/2);

Self.canshowcallout = NO;

Self.avatarview = [[Uiimageview alloc] initWithFrame:self.bounds];

[Self addSubview:self.avatarView];

Self.avatarView.contentMode = Uiviewcontentmodescaleaspectfill;

Cashapelayer *shapelayer = [Cashapelayer layer];

Shapelayer.frame = Self.bounds;

Shapelayer.path = Self.framePath.CGPath;

Self.avatarView.layer.mask = Shapelayer;

Self.layer.shadowPath = Self.framePath.CGPath;

Self.layer.shadowRadius = 1.0f;

Self.layer.shadowColor = [Uicolor colorwithhex:0x666666ff]. Cgcolor;

self.layer.shadowOpacity = 1.0f;

Self.layer.shadowOffset = cgsizemake (0, 0);

Self.layer.masksToBounds = NO;

}

return self;

}

Mask path

-(Uibezierpath *) Framepath

{

if (!_framepath)

{

CGFloat arrowwidth = 14;

Cgmutablepathref path = cgpathcreatemutable ();

CGRect rectangle = cgrectinset (cgrectmake (0, 0, cgrectgetwidth (self.bounds), Cgrectgetwidth (Self.bounds)), 3,3);

Cgpoint P[3] = {

{Cgrectgetmidx (self.bounds)-ARROWWIDTH/2, Cgrectgetwidth (self.bounds)-6},

{Cgrectgetmidx (self.bounds) +ARROWWIDTH/2, Cgrectgetwidth (self.bounds)-6},

{Cgrectgetmidx (self.bounds), Cgrectgetheight (Self.bounds)-4}

};

Cgpathaddroundedrect (path, NULL, Rectangle, 5, 5);

Cgpathaddlines (Path, NULL, p, 3);

Cgpathclosesubpath (path);

_framepath = [Uibezierpath Bezierpathwithcgpath:path];

Cgpathrelease (path);

}

return _framepath;

}

I generated the shape path using code and generated the layer mask and Shadowpath

When you use it, just use Sdwebimage to set the avatar.

1

[Annotationview.avatarview Sd_setimagewithurl:[nsurl Urlwithstring:avatarurl] placeholderimage:placeholderimage];

Then use the tools to analyze the problem. The analysis performance of course is to choose instrments (usage is not introduced here) open the core Animation and then run the program slide map can see the performance analysis as follows

The original average frame number is less than 30 frames, which is far from our target of 60 frames.

And then use debug option to drill down on

Because of the mkmapview reason here we are mainly concerned with these several options

Color Blended Layers

Color misaligned Images

Color offscreen-rendered Yellow

Opening these options separately results in the following

Can see

Color blended layers no problem, but it's normal. Because of the use of mask no transparent place

Color misaligned images except the default avatar this is because the size of the picture on the server is inconsistent with the size of the display, and the default avatar is the same, so no problem.

Color offscreen-rendered Yellow Because of the use of mask led to a large number of off-screen rendering this is the main reason for performance degradation

Solve

The cause of the problem has been found then how to solve it then?

First of all, mask is definitely not going to work.

Next download down the picture we want to preprocess into the actual size

So just put the downloaded pictures into the final results we want to display is not OK? Try

-(void) Loadannotationimagewithurl: (nsstring*) URL ImageView: (uiimageview*) ImageView

{

To cache the synthesized picture

NSString *annoimageurl = URL;

NSString *annoimagecacheurl = [Annoimageurl stringbyappendingstring:@ "Cache"];

UIImage *cacheimage = [[Sdimagecache Sharedimagecache] imagefromdiskcacheforkey:annoimagecacheurl];

if (cacheimage)

{

Lllog (@ "hit cache");

Imageview.image = Cacheimage;

}

Else

{

Lllog (@ "no cache");

[ImageView Sd_setimagewithurl:[nsurl Urlwithstring:annoimageurl]

Placeholderimage:placeholderimage

completed:^ (UIImage *image, Nserror *error, Sdimagecachetype cachetype, Nsurl *imageurl) {

if (!error)

{

UIImage *annoimage = [Image annotationimage];

Imageview.image = Annoimage;

[[Sdimagecache Sharedimagecache] Storeimage:annoimage Forkey:annoimagecacheurl];

}

}];

}

}

@implementation UIImage (LJC)

-(uiimage*) annotationimage

{

static UIView *snapshotview = nil;

static Uiimageview *imageview = nil;

if (!snapshotview)

{

Snapshotview = [UIView new];

Snapshotview.frame = CGRectMake (0, 0, track_annotation_size.width, track_annotation_size.height);

ImageView = [Uiimageview new];

[Snapshotview Addsubview:imageview];

Imageview.clipstobounds = YES;

Imageview.frame = Snapshotview.bounds;

Imageview.contentmode = Uiviewcontentmodescaleaspectfill;

CGFloat arrowwidth = 14;

Cgmutablepathref path = cgpathcreatemutable ();

CGRect rectangle = cgrectinset (cgrectmake (0, 0, cgrectgetwidth (imageview.bounds), Cgrectgetwidth (Imageview.bounds)), 3,3);

Cgpoint P[3] = {

{Cgrectgetmidx (imageview.bounds)-ARROWWIDTH/2, Cgrectgetwidth (imageview.bounds)-6},

{Cgrectgetmidx (imageview.bounds) +ARROWWIDTH/2, Cgrectgetwidth (imageview.bounds)-6},

{Cgrectgetmidx (imageview.bounds), Cgrectgetheight (Imageview.bounds)-4}

};

Cgpathaddroundedrect (path, NULL, Rectangle, 5, 5);

Cgpathaddlines (Path, NULL, p, 3);

Cgpathclosesubpath (path);

Cashapelayer *shapelayer = [Cashapelayer layer];

Shapelayer.frame = Imageview.bounds;

Shapelayer.path = path;

ImageView.layer.mask = Shapelayer;

SnapshotView.layer.shadowPath = path;

SnapshotView.layer.shadowRadius = 1.0f;

SnapshotView.layer.shadowColor = [Uicolor colorwithhex:0x666666ff]. Cgcolor;

snapshotView.layer.shadowOpacity = 1.0f;

SnapshotView.layer.shadowOffset = cgsizemake (0, 0);

Cgpathrelease (path);

}

Imageview.image = self;

Uigraphicsbeginimagecontextwithoptions (track_annotation_size, NO, 0);

[Snapshotview.layer Renderincontext:uigraphicsgetcurrentcontext ()];

UIImage *copied = Uigraphicsgetimagefromcurrentimagecontext ();

Uigraphicsendimagecontext ();

return copied;

}

@end

And then use it as long as the simple following call is OK

[Self loadannotationimagewithurl:avatarurl imageView:annotationView.avatarView];

See how the instruments behaved after the change.

Color blended layers All of this is unavoidable because it shows a picture with transparency. But because of the specificity of the map (the avatar position varies a long interval so it doesn't often cause compositing or animation) so it's not a problem here.

Color misaligned images No problem, because the avatar has been scaled to the same size

Color offscreen-rendered Yellow No problem, because it simply shows a picture and there's no need to leave the screen to render the thing.

Let's look at the number of frames.

Oh-yeah~ not only the number of frames to reach our target 60 frames (because there are also business logic threads running in the background so not so stable) even the average running time has dropped a lot even if the map to show more than dozens of people is not a problem

Summary

Not only mkmapview in fact, including UITableView in many places can be described in the method to optimize its core point is the synthesis + cache of course, because of the synthesis or will consume a portion of resources, so it is more suitable for the head of this small resource

About graphic performance optimization You can look at this good article (there is a detailed explanation for the debug option that is mentioned in the article)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.