1

UICalloutView willRemoveSubview:]: 割り当て解除されたインスタンスに送信されたメッセージ。

これは、吹き出しボタンをタップしたときにのみ発生しますが、最初のタップではなく、2回目のタップではなく、3回目のタップから発生します。そこで、カスタムAnnotationViewのコールアウト ポップをタップします。もう一度タップすると、コールアウトが表示されます。すべて問題ありません。別のものをタップすると、そのメッセージとともにブームがクラッシュします。正しいアクセサリビューがボタンに設定されている場合にのみ発生します。

心に留めておくべき 1 つの重要な側面..iOS 6 でのみ発生します... (図を参照)。

私は本当にこれにこだわっています - 助けていただければ幸いです。

if ([annotation isKindOfClass:[RE_Annotation class]])
{
    RE_Annotation *myAnnotation = (RE_Annotation *)annotation;

    static NSString *annotationIdentifier = @"annotationIdentifier";

    RE_AnnotationView *newAnnotationView = (RE_AnnotationView *)[mapViews dequeueReusableAnnotationViewWithIdentifier:annotationIdentifier];


    if(newAnnotationView)
    {
        newAnnotationView.annotation = myAnnotation;
    }
    else
    {
        newAnnotationView = [[RE_AnnotationView alloc] initWithAnnotation:myAnnotation reuseIdentifier:annotationIdentifier];
    }

    return newAnnotationView;
}
return nil;

また、これは私のinitwithannotation方法です:

- (id)initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier
{

    self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
    if(self)
    {

    RE_Annotation *myAnnotation = annotation;

    self = [super initWithAnnotation:myAnnotation reuseIdentifier:reuseIdentifier];

    self.frame = CGRectMake(0, 0, kWidth, kHeight);

    self.backgroundColor = [UIColor clearColor];

    annotationView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"map_pin_pink.png"]];

    annotationView.frame = CGRectMake(0, 0, kWidth - 2 *kBorder, kHeight - 2 * kBorder);



    [self addSubview:annotationView];

    [annotationView setContentMode:UIViewContentModeScaleAspectFill];

    self.canShowCallout = YES;

     self.rightCalloutAccessoryView = [[UIButton buttonWithType:UIButtonTypeInfoLight] retain]; ///if i take it out it doesnt crash the app. if i leave it it says that message
    }

    return self ;

}
4

1 に答える 1

1

initWithAnnotationメソッドには、次の行があります。

self.rightCalloutAccessoryView = 
    [[UIButton buttonWithType:UIButtonTypeInfoLight] retain]; 
///if i take it out it doesnt crash the app. if i leave it it says that message

「それ」とは、を指している必要がありretain、これはアプリが ARC を使用していないことを意味します。


それに基づいて、次の修正を行う必要があります。

  • では、 alloc+init するときにビューviewForAnnotationが必要です。そうしないと、リークが発生します。autorelease

    newAnnotationView = [[[RE_AnnotationView alloc] 
        initWithAnnotation:myAnnotation 
        reuseIdentifier:annotationIdentifier] autorelease];
    
  • では、吹き出しボタンを作成するときに をinitWithAnnotation削除します。これは、自動解放されたオブジェクトを返すためです (これを保持しすぎないようにします)。retainbuttonWithType

    self.rightCalloutAccessoryView = 
        [UIButton buttonWithType:UIButtonTypeInfoLight];
    


無関係の可能性があるもう 1 つの問題は、 でinitWithAnnotationコードがsuper initWithAnnotation2 回呼び出されていることです。これは不要なようで、有害な場合があります。2 番目の呼び出しを削除します。


上記の変更により、少なくとも表示されているコードの問題が修正されます。ただし、アプリの残りの部分には、クラッシュを引き起こす可能性のある他の同様のメモリ管理関連の問題がある可能性があります。Analyzer によって報告されたすべての問題を確認して解決します。

「iOS 6 でのみ発生する」という事実について: iOS 6 ではメモリ管理エラーが許容されないか、SDK の内部変更によってこれらのエラーが以前に公開または明示されている可能性があります。とにかく、上記の修正が必要です。


無関係な点は、注釈ビューUIImageViewに 手動で作成する必要がないことです。注釈ビューのプロパティaddSubviewを設定するだけです。image

于 2013-01-24T14:08:42.333 に答える