2

为 MapKit 设置单独的委托类的正确方法是什么?

我有 MapView 类子类化 MKMapView 和符合 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 类的寿命比现在长(委托属性具有属性)。如果我执行以下操作:

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

...有用!是否有更好的方法来保留 MapDelegate 生命周期以及 MKMapView 的生命周期?

谢谢!

4

2 回答 2

2

在等待足够长的时间等待可能出现在这里的任何答案并确保原始有问题的行为两次以上之后,我将根据问题的第二次更新发布我自己的答案:

[self setDelegate:[[MapDelegate alloc] initWithMapView:self]]; 的问题 string 是 MapDelegate 类应该能够在问题的initWithFrame方法范围之外保持活动状态,因为委托属性具有属性。可能的解决方案是创建一个实例变量作为委托类的容器,例如:

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

这解决了原来的问题。

稍后更新

虽然可以在单独的类中设置 MKMapView 的委托,但我现在意识到不应该使用这样的模型:

Currently I always prefer to use my controllers (i.e. controller layer in MVC in general) as delegates for all of my View layer classes (map view, scroll view, text fields): controller level is the place where all the delegates of different views can meet - all situated in controller layer, they can easily interact with each other and share their logic with the general logic of your controller.

On the other hand, if you setup your delegate in a separate class, you will need to take additional steps to connect your separate delegate with some controller, so it could interact with a rest part of your logic - this work have always led me to adding additional and messy pieces of code.

很快:不要为委托使用单独的类(至少 Apple 提供的视图类委托),使用一些常见的地方,如控制器(对于 UIScrollView、MKMapView、UITableView 等视图或 NSURLConnection 等模型的 fx)。

于 2012-09-17T22:31:41.790 回答
0

我认为viewDidLoad设置地图视图会更好。这只是一个猜测,但可能崩溃是由于尚未加载视图。

当然MKMapView,根本不推荐子类化。您通常会将您的地图作为子视图,并将主视图设置为委托。从文档:

尽管您不应该继承 MKMapView 类本身,但您可以通过提供委托对象来获取有关地图视图行为的信息。

最后,如果您真的想拥有一个单独的委托类,则不需要设置它mapView,因为所有委托方法都将映射作为参数传递。

于 2012-09-13T23:27:30.853 回答