我正在调用一个Web服务,该服务在委托方法中返回一个注释数组,我将addAnnotations
方法添加到我的地图中MKMapView
。一切顺利,直到委托方法快速连续发送两个数组(通常约150毫秒 - 500毫秒),然后我在这一行EXC_BAD_ACCESS (code=1 address 0x20)
得到一个[kMap addAnnotations:tileArray];
- 这似乎是一个内存问题,但我不是我真的很清楚该怎么做或如何改变我的代码来解决它。
这是委托方法
-(void)rebelBaseManager:(RebelBaseManager *)manager didUpdateTileHour:(NSArray *)tileArray boundaryBreak:(NSString *)breakType atTileLevel:(int)callTileLevel {
if (timerStarted == NO) {
[self startTimer];
}
//Check for tileLevel in case multiple calls were made at different tile levels
if (tileLevel == callTileLevel) {
[kMap addAnnotations:tileArray];
[HourInMap addObjectsFromArray:tileArray];
}
}
我还添加了一种方法,允许我动画删除注释,如果它有所作为:
- (void)removeAnnotationsWithFade:(NSArray *)annotations animated:(BOOL)shouldAnimate {
if (!shouldAnimate)
[self removeAnnotations:annotations];
else {
for (HourAnnotation *annotation in annotations) {
MKAnnotationView *annotationView = [self viewForAnnotation:annotation];
[UIView animateWithDuration:2
animations:^{
annotationView.alpha =0;
}completion:^(BOOL finished) {
[self removeAnnotation:annotation];
}];
}
}
--------- ADDITION ---------
在Rob的答案中添加自定义注释的代码以响应#3。
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
- (id)initWithHourAnnotation:(HourAnnotation *)hourAnnotation reuseIdentifier:(NSString *)reuseIdentifier {
CGRect myFrame = self.frame;
myFrame.size.width = hourAnnotation.frameSize;
myFrame.size.height = hourAnnotation.frameSize;
self = [super initWithFrame:myFrame];
//When I use this here I seem to get the frame and color of the old annotation displayed
//self = [super initWithAnnotation:velocityAnnotation reuseIdentifier:reuseIdentifier];
if (self)
{
self.layer.cornerRadius = self.frame.size.width / 2;
self.clipsToBounds = YES;
[self setBackgroundColor:[UIColor clearColor]];
NSArray *alphaValue = [[NSArray alloc]initWithArray:[self alphaForTileLevel]];
self.fillColor = [UIColor colorWithHue:hourAnnotation.color saturation:.06 brightness:.23 alpha:[[alphaValue objectAtIndex:hourAnnotation.tileLevel-1]doubleValue]];
self.strokeColor = [UIColor colorWithHue:hourAnnotation.color saturation:.06 brightness:.23 alpha:.35];
self.enabled = NO;
self.canShowCallout = NO;
self.userInteractionEnabled = NO;
}
return self;
}
- (void)drawRect:(CGRect)rect
{
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:rect];
[self.fillColor set];
[path fill];
[self.strokeColor set];
[path setLineWidth:2.0f];
[path stroke];
}
答案 0 :(得分:2)
一些想法。
您没有显示您调用此removeAnnotationsWithFade
的位置。我们必须假设您正在删除相应的模型对象。使用仪器确认您没有泄漏到任何地方。
如果应用程序在使用淡入淡出删除时崩溃,但没有淡入淡出则崩溃,那么您可以考虑重构此代码。具体来说,您的动画代码实际上并没有删除旧动画,直到完成块(即两秒钟后)。因此,您将持续比所需更长的旧注释。如果注释快速而激烈,你可能会遇到内存问题。
例如,如果您使用transitionWithView:mapView
而只是直接删除注释,则可能会更快地释放与旧注释关联的内存。这是一个不太优雅的动画,但可能“足够好”并最小化你的峰值内存使用量:
// this will immediately remove the annotations, but animate the fading of the transition
[UIView transitionWithView:self.mapView duration:2.0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
[self.mapView removeAnnotations:annotations];
} completion:nil];
// presumably remove the annotations from your array, too
你的viewForAnnotation
出列旧注释视图,如果它不能使旧注释出现,或者它是否总是实例化新注释,那么它只是实例化新注释?这样的东西也可能有助于控制峰值内存使用量。