Подвид CATiledLayer, приводящий к предупреждению памяти и сбою
Хорошо, вот что происходит... У меня есть подкласс UIView, который включает в себя две точки (начало и конец), CGPath между этими двумя точками и множество UILabels. Если я добавлю этот подкласс UIView в качестве подпредставления к моему scrollview (поверх моего UIView, основанного на CATiledLayer), тогда мое приложение начнет получать предупреждения памяти и в конечном итоге вылетает. Однако, если я удаляю подкласс UIView, который содержит точки и путь, и оставляю представление CATiledLayer как есть, все работает отлично, и не происходит никаких сбоев или предупреждений памяти.
У кого-нибудь есть идеи о том, почему это происходит? У представления содержимого не должно быть проблем с его большим размером, так как я рисую только метки с максимальной шириной 40 пикселей и CGPath, который также довольно мал?
Это картографическое приложение
Вот некоторый код:
//Display the map image
- (void)displayTiledImageNamed:(NSString *)imageName size:(CGSize)imageSize {
self.zoomScale = 1.0;
container = [[UIView alloc] initWithFrame:(CGRect){ CGPointZero, imageSize }];
_zoomView = [[UIImageView alloc] initWithFrame:(CGRect){ CGPointZero, imageSize }];
NSString *path = [NSString stringWithFormat:@"%@/%@-Small.png",[[NSBundle mainBundle] bundlePath], [imageName stringByDeletingPathExtension]];
UIImage *zoomImage = [UIImage imageWithContentsOfFile:path];
[_zoomView setImage:zoomImage];
[container addSubview:_zoomView];
[_zoomView release];
_tilingView = [[UMTileView alloc] initWithImageName:imageName size:imageSize];
_tilingView.frame = _zoomView.bounds;
[_zoomView addSubview:_tilingView];
[_tilingView release];
[self configureForImageSize:imageSize];
//This is the view that's causing the crash and memory warnings
//If this view is commented out the app functions just fine
UMMapContentView *m = [[UMMapContentView alloc] initWithFrame:CGRectMake(0,0,imageSize.width,imageSize.height) andColors:self.colors mapView:self.mapView];
self.contentView = m;
[container addSubview:self.contentView];
[m release];
[self addSubview:container];
[container release];
}
Это мой класс представления пути, который является другим подпредставлением внутри представления UMMapContentView выше:
+ (Class)layerClass {
return [CATiledLayer class];
}
+ (CFTimeInterval)fadeDuration {
return 0.0;
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.userInteractionEnabled = NO;
self.backgroundColor = [UIColor clearColor];
}
return self;
}
- (void)dealloc {
self.path = nil;
self.pathColor = nil;
[super dealloc];
}
- (void)resetPathView {
CATiledLayer *tiledLayer = (CATiledLayer*)self.layer;
tiledLayer.contents = nil;
[tiledLayer setNeedsDisplay];
}
- (void)drawPath:(UMPath*)p {
self.path = p;
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect {
if (self.path) {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, self.pathColor.CGColor);
CGContextSetShadowWithColor(context, CGSizeMake(2.0, 1.0), 1.0, [[UIColor colorWithWhite:0.2 alpha:0.8] CGColor]);
CGContextSetLineWidth(context, 8.0);
CGContextBeginPath (context);
CGContextMoveToPoint (context, ((UMMapPoint*)[self.path.points objectAtIndex: 0]).x, ((UMMapPoint*)[self.path.points objectAtIndex: 0]).y);
for (int i = 1; i < self.path.points.count; i++) {
CGContextAddQuadCurveToPoint (context, ((UMMapPoint*)[self.path.points objectAtIndex:i-1]).x, ((UMMapPoint*)[self.path.points objectAtIndex: i-1]).y, ((UMMapPoint*)[self.path.points objectAtIndex:i]).x, ((UMMapPoint*)[self.path.points objectAtIndex:i]).y);
}
CGContextStrokePath (context);
}
}
И это мой метод, который помещает все UILabels в представление UMMapContentView:
- (void)mapAllLabelsInNavigationMap:(int)navigationMap {
//There are 1109 label dictionaries in the labels array
for (NSDictionary *dict in labels) {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake([[dict objectForKey:@"X"] floatValue],[[dict objectForKey:@"Y"] floatValue],[[dict objectForKey:@"Width"] floatValue],[[dict objectForKey:@"Height"] floatValue])];
[label setLineBreakMode:NSLineBreakByWordWrapping];
[label setNumberOfLines:0];
[label setBackgroundColor:[UIColor clearColor]];
[label setTextColor:[self colorFromHexString:[dict objectForKey:@"Foreground"]]];
[label setFont:[UIFont systemFontOfSize:[[dict objectForKey:@"FontSize"] floatValue]]];
[label setTextAlignment:NSTextAlignmentCenter];
[label setText:[[UMDataBase shared] stringForID:[[dict objectForKey:@"Texts_ID"] intValue] withLanguage:languageID]];
[self addSubview:label];
[localMapLabels addObject:label];
[label release];
}
}
Я не совсем уверен, в каком направлении мне нужно идти... Любая помощь будет высоко ценится!:)
1 ответ
Вы не дали исходный код UMMapContentView
, но если он использует CATiledLayer, то это может быть проблемой. Кажется, что вы не можете подписать представление с поддержкой CATiledLayer.
Прокрутите вниз (в разделе комментариев): http://red-glasses.com/index.php/tutorials/catiledlayer-how-to-use-it-how-it-works-what-it-does/
Это может быть проще, если вы все равно напишите свой собственный плиточный слой. Документация на CATiledLayer редкая, а ошибок много.