From 43de62650b1e4d62109db4e320382e5925093b3d Mon Sep 17 00:00:00 2001 From: Horcrux Date: Sat, 6 Aug 2016 22:57:15 +0800 Subject: [PATCH] fix memory leaks --- Example/examples/TouchEvents.js | 5 +-- ios/Elements/RNSVGGroup.m | 69 +++++++++++++++++++-------------- ios/Elements/RNSVGPath.m | 32 ++++++++------- ios/Elements/RNSVGSvgView.m | 11 ++++-- ios/RNSVGRenderable.m | 1 + 5 files changed, 70 insertions(+), 48 deletions(-) diff --git a/Example/examples/TouchEvents.js b/Example/examples/TouchEvents.js index 15527cb8..4a5effeb 100644 --- a/Example/examples/TouchEvents.js +++ b/Example/examples/TouchEvents.js @@ -69,7 +69,6 @@ class HoverExample extends Component { x="0" y="0" scale="1.2" - opacity="0.3" /> @@ -87,9 +86,9 @@ class GroupExample extends Component { viewBox="0 0 240 240" > - + alert('Pressed')}> - alert('Pressed')}/> + H diff --git a/ios/Elements/RNSVGGroup.m b/ios/Elements/RNSVGGroup.m index 64d46845..ac688d58 100644 --- a/ios/Elements/RNSVGGroup.m +++ b/ios/Elements/RNSVGGroup.m @@ -15,27 +15,30 @@ RNSVGSvgView* svg = [self getSvgView]; [self clip:context]; - for (RNSVGNode *node in self.subviews) { - if ([node isKindOfClass:[RNSVGNode class]]) { - [node mergeProperties:self mergeList:self.propList inherited:YES]; - [node renderTo:context]; - - if (node.responsible && !svg.responsible) { - svg.responsible = YES; - } + [self traverseSubviews:^(RNSVGNode *node) { + if (node.responsible && !svg.responsible) { + svg.responsible = YES; + return NO; } - } + return YES; + }]; + + [self traverseSubviews:^(RNSVGNode *node) { + [node mergeProperties:self mergeList:self.propList inherited:YES]; + [node renderTo:context]; + return YES; + }]; } - (CGPathRef)getPath:(CGContextRef)context { CGMutablePathRef path = CGPathCreateMutable(); - for (RNSVGNode *node in self.subviews) { - if ([node isKindOfClass:[RNSVGNode class]]) { - CGAffineTransform transform = node.matrix; - CGPathAddPath(path, &transform, [node getPath:context]); - } - } + [self traverseSubviews:^(RNSVGNode *node) { + CGAffineTransform transform = node.matrix; + CGPathAddPath(path, &transform, [node getPath:context]); + return YES; + }]; + return (CGPathRef)CFAutorelease(path); } @@ -47,9 +50,7 @@ if ([node isKindOfClass:[RNSVGNode class]]) { if (event) { node.active = NO; - } - - if (node.active) { + } else if (node.active) { return node; } @@ -76,29 +77,39 @@ [svg defineTemplate:self templateRef:self.name]; } - for (RNSVGNode *node in self.subviews) { - if ([node isKindOfClass:[RNSVGNode class]]) { - [node saveDefinition]; - } - } + [self traverseSubviews:^(RNSVGNode *node) { + [node saveDefinition]; + return YES; + }]; + } - (void)mergeProperties:(__kindof RNSVGNode *)target mergeList:(NSArray *)mergeList { - for (RNSVGNode *node in self.subviews) { - if ([node isKindOfClass:[RNSVGNode class]]) { - [node mergeProperties:target mergeList:mergeList]; - } - } + [self traverseSubviews:^(RNSVGNode *node) { + [node mergeProperties:target mergeList:mergeList]; + return YES; + }]; } - (void)resetProperties +{ + [self traverseSubviews:^(RNSVGNode *node) { + [node resetProperties]; + return YES; + }]; +} + +- (void)traverseSubviews:(BOOL (^)(RNSVGNode *node))block { for (RNSVGNode *node in self.subviews) { if ([node isKindOfClass:[RNSVGNode class]]) { - [node resetProperties]; + if (!block(node)) { + break; + } } } } + @end diff --git a/ios/Elements/RNSVGPath.m b/ios/Elements/RNSVGPath.m index 2392afdc..705612b6 100644 --- a/ios/Elements/RNSVGPath.m +++ b/ios/Elements/RNSVGPath.m @@ -28,25 +28,31 @@ - (void)renderLayerTo:(CGContextRef)context { - CGPathRef path = [self getPath:context]; + if (!self.d) { + self.d = [self getPath:context];; + } + CGPathRef path = self.d; if ((!self.fill && !self.stroke) || !path) { return; } - // Add path to hitArea - CGMutablePathRef hitArea = CGPathCreateMutableCopy(path); - if (self.stroke) { - // Add stroke to hitArea - CGPathRef strokePath = CGPathCreateCopyByStrokingPath(hitArea, nil, self.strokeWidth, self.strokeLinecap, self.strokeLinejoin, self.strokeMiterlimit); - CGPathAddPath(hitArea, nil, strokePath); - CGPathRelease(strokePath); + if ([self getSvgView].responsible) { + NSLog(@"asdasdasdsadas"); + + // Add path to hitArea + CGMutablePathRef hitArea = CGPathCreateMutableCopy(path); + if (self.stroke) { + // Add stroke to hitArea + CGPathRef strokePath = CGPathCreateCopyByStrokingPath(hitArea, nil, self.strokeWidth, self.strokeLinecap, self.strokeLinejoin, self.strokeMiterlimit); + CGPathAddPath(hitArea, nil, strokePath); + CGPathRelease(strokePath); + } + + CGAffineTransform transform = self.matrix; + self.hitArea = CFAutorelease(CGPathCreateCopyByTransformingPath(hitArea, &transform)); + CGPathRelease(hitArea); } - CGAffineTransform transform = self.matrix; - self.hitArea = CGPathCreateCopyByTransformingPath(hitArea, &transform); - - CGPathRelease(hitArea); - if (self.opacity == 0) { return; } diff --git a/ios/Elements/RNSVGSvgView.m b/ios/Elements/RNSVGSvgView.m index 58074ac8..7cda66c6 100644 --- a/ios/Elements/RNSVGSvgView.m +++ b/ios/Elements/RNSVGSvgView.m @@ -50,14 +50,19 @@ for (RNSVGNode *node in self.subviews) { if ([node isKindOfClass:[RNSVGNode class]]) { - [node saveDefinition]; - [node renderTo:context]; - if (node.responsible && !self.responsible) { self.responsible = YES; + break; } } } + + for (RNSVGNode *node in self.subviews) { + if ([node isKindOfClass:[RNSVGNode class]]) { + [node saveDefinition]; + [node renderTo:context]; + } + } // CGImageRef image = CGBitmapContextCreateImage(context); // NSData *imageData = UIImagePNGRepresentation([[UIImage alloc] initWithCGImage:image]); // NSString *base64 = [imageData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]; diff --git a/ios/RNSVGRenderable.m b/ios/RNSVGRenderable.m index f3157b7b..2c42abe6 100644 --- a/ios/RNSVGRenderable.m +++ b/ios/RNSVGRenderable.m @@ -145,6 +145,7 @@ CGPathRef hitArea = CGPathCreateCopyByTransformingPath(self.hitArea, &transfrom); CGPathRef clipPath = self.clipPath; BOOL contains = CGPathContainsPoint(hitArea, nil, point, NO); + CGPathRelease(hitArea); if (contains) { if (!clipPath) { return self;