2

MapKit の別のデリゲート クラスをセットアップする適切な方法は何ですか?

MKMapView をサブクラス化する MapView クラスと、初期化メソッドが 1 つしかない MKMapViewDelegate プロトコルに準拠する裸の MapDelegate クラスがあります。

以下は、私が使用する MapView 初期化メソッドからの抜粋です。

# MapView.m ...
@implementation MapView

- (id) initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {

    // [self setShowsUserLocation:YES];

    [self setDelegate:[[MapDelegate alloc] initWithMapView:self]];

MapDelegate クラスが持つ唯一のメソッドは

# MapDelegate.m ...
- (id)initWithMapView:(MapView *)aMapView {
    self = [super init];
    self.mapView = aMapView;
    return self;
}

[self setShowsUserLocation :YES] を持っています。コメント、すべて正常に動作します-マップが表示されます。この行のコメントを外すと、アプリケーションがクラッシュし始めます。

私の MapDelegate クラスには何が欠けていますか?

更新 1: 別のクラス MapDelegate を使用せず、setDelegate:self だけを設定すると、すべて機能します。

更新 2: [self setDelegate:[[MapDelegate alloc] initWithMapView:self]];の問題がわかりました。文字列は、MapDelegate クラスが現在よりも長く存続する必要があることです (delegate プロパティには弱い属性があります)。私が次のことをした場合:

@property (strong) id delegateContainer;
....
[self setDelegateContainer:[[MapDelegate alloc] init]];
[self setDelegate:self.delegateContainer];

...できます!MKMapView のライフ サイクルと共に MapDelegate のライフ サイクルを保持するより良い方法はありますか?

ありがとう!

4

2 に答える 2

2

ここに表示される可能性のある回答を十分に待って、元の問題のある動作をさらに2回確認した後、質問の2番目の更新に基づいて自分の回答を投稿します。

[self setDelegate:[[MapDelegate alloc] initWithMapView:self]]の問題; 文字列は、デリゲートプロパティの属性が弱いため、MapDelegateクラスを質問のinitWithFrameメソッドのスコープ外で存続させることができるようにする必要があるということです。考えられる解決策は、デリゲートクラスのコンテナとして機能するインスタンス変数を作成することです。次に例を示します。

@property (strong) id delegateClass;
....
[self setDelegateClass:[[MapDelegate alloc] init]];
[self setDelegate:self.delegateClass];

これにより、元の問題が解決されます。

後の更新

MKMapViewのデリゲートを別のクラスに設定することは可能ですが、そのようなモデルは使用しないでください。

現在、私は常にコントローラー(つまり、MVCのコントローラーレイヤー)をすべてのビューレイヤークラス(マップビュー、スクロールビュー、テキストフィールド)のデリゲートとして使用することを好みます。コントローラーレベルは、さまざまなビューのすべてのデリゲートができる場所です。会う-すべてコントローラーレイヤーに配置されており、簡単に相互作用し、コントローラーの一般的なロジックとロジックを共有できます。

一方、デリゲートを別のクラスに設定する場合は、別のデリゲートをコントローラーに接続するために追加の手順を実行する必要があります。これにより、ロジックの残りの部分と相互作用できるようになります。この作業により、常に追加の厄介なコードを追加します。

簡単に言うと、デリゲートに個別のクラスを使用せず(少なくとも、Appleが提供するビュークラスデリゲート)、コントローラーなどの一般的な場所を使用します(UIScrollView、MKMapView、UITableViewなどのビューまたはNSURLConnectionなどのモデルの場合はfx)。

于 2012-09-17T22:31:41.790 に答える
0

viewDidLoadマップビューを設定するのに適した場所だと思います。これは単なる推測ですが、おそらくクラッシュはビューがまだロードされていないことが原因です。

もちろん、サブクラス化MKMapViewはまったくお勧めしません。通常、マップをサブビューとして配置し、メインビューをデリゲートに設定します。ドキュメントから:

MKMapViewクラス自体をサブクラス化するべきではありませんが、デリゲートオブジェクトを提供することで、マップビューの動作に関する情報を取得できます。

最後に、本当に別のデリゲートクラスが必要な場合はmapView、すべてのデリゲートメソッドがマップを引数として渡すため、そのクラスを設定する必要はありません。

于 2012-09-13T23:27:30.853 に答える