自定义 MKAnnotation 总是说它是 MKUserLocation 类

发布于 2024-10-16 09:38:20 字数 4126 浏览 1 评论 0原文

我有一个名为 Device 的自定义类,它实现了 MKAnnotation 协议。在我下面的示例中(O'Reilly Media 的 iPad 上的 MapKit 和 Core Location),他们说要检查我要添加的注释是否是 MKUserLocation 类,如果是则返回 nil 。我完全理解它的作用,但问题是我的 Device 类始终被标识为 MKUserLocation 因此它总是返回 nil,所以我永远不会将任何注释添加到地图中。我一遍又一遍地检查代码。我也有 O'Reilly 代码示例,但我不知道我要去哪里。真是令人沮丧。

这是我的 Device.m

@implementation Device

@synthesize udId, user, latitude, longitude;

- (CLLocationCoordinate2D)coordinate {
    CLLocationCoordinate2D internalCoordinate;

    internalCoordinate.latitude = [self.latitude doubleValue];
    internalCoordinate.longitude = [self.longitude doubleValue];

    return internalCoordinate;
}

- (NSString *)title {
    return self.user;
}

- (NSString *)subtitle {
    return nil;
}

- (id)initWithUDId:(NSString *)_udId User:(NSString *)_user Latitude:(NSNumber *)_latitude Longitude:(NSNumber *)_longitude {
    if (self == [super init]) {
        self.udId = _udId;
        self.user = _user;
        self.latitude = _latitude;
        self.longitude = _longitude;
    }

    return self;
}

- (void)dealloc {
    [udId release];
    self.udId = nil;

    [user release];
    self.user = nil;

    [latitude release];
    self.latitude = nil;

    [longitude release];
    self.longitude = nil;

    [super dealloc];
}

@end

这是我的 DeviceMapAnnotator.m

@implementation DeviceMapAnnotator

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
    if ([annotation isKindOfClass:[MKUserLocation class]]) {
        NSLog(@"annotation is an MKUserLocation class");

        return nil;
    }

    MKPinAnnotationView *deviceAnnotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"DeviceAnnotation"];

    if (deviceAnnotationView == nil) {
        deviceAnnotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"DeviceAnnotation"] autorelease];
        deviceAnnotationView.animatesDrop = NO;
        deviceAnnotationView.pinColor = MKPinAnnotationColorRed;
    }

    return deviceAnnotationView;
}

- (void)dealloc {
    [super dealloc];
}

@end

这是从我的 DashboardViewController.m 调用它的代码:

- (void)updateMapAnnotations:(NSArray *)devices {
    for (Device *device in devices) {
        [map addAnnotation:device];
    }
}

这是代码从我的应用程序委托调用 updateMapAnnotations

- (void)requestFinished:(ASIHTTPRequest *)request {
    if (![request error]) {
        NSError *jsonError = nil;
        NSDictionary *jsonDictionary = [NSDictionary dictionaryWithJSONString:[request responseString] error:&jsonError];

        if (!jsonError || ([[jsonDictionary objectForKey:@"Success"] intValue] == 1)) {
            NSArray *jsonDevicesArray = [jsonDictionary objectForKey:@"Devices"];
            NSMutableArray *devicesArray = [[NSMutableArray alloc] initWithCapacity:[jsonDevicesArray count]];

            for (NSDictionary *deviceDictionary in jsonDevicesArray) {
                [devicesArray addObject:[[[Device alloc] initWithUDId:[deviceDictionary objectForKey:@"UDId"] User:[deviceDictionary objectForKey:@"User"] Latitude:[NSNumber numberWithDouble:[[deviceDictionary objectForKey:@"Latitude"] doubleValue]] Longitude:[NSNumber numberWithDouble:[[deviceDictionary objectForKey:@"Longitude"] doubleValue]]] autorelease]];
            }

            [dashboardViewController updateMapAnnotations:devicesArray];
        } else {
            //  AUTHORIZATION FAILED
        }
    }
}

我基本上每 45 秒调用一次服务器,以 JSON 字符串形式获取设备及其位置列表,然后将其反序列化为 NSArray 包含 Device 对象。然后,我将数组传递给 updateMapAnnotations,然后循环它并调用 addAnnotation。整个过程有效,我保证发送到 DeviceMapAnnotator 的对象属于 Device 类型,但是 MKUserLocation 检查总是过早返回,并且整个过程就在水中停止了。

如果有人知道他们在使用 iOS/Objective-C 等做什么,可以帮助我(这几乎是每个人,因为我显然是个白痴),我将非常感激。

只是为了发泄一下,我必须说 Objective-C 很快就进入了我的热门列表。

I have a custom class called Device which implements the MKAnnotation protocol. In the examples I'm following (MapKit and Core Location on the iPad from O'Reilly Media), they say to check if the annotation I want to add is an MKUserLocation class and return nil if it is. I fully understand what that does, but the problem is that my Device class is always identified as MKUserLocation so it always returns nil so I never get any annotations added to the map. I've gone over the code again and again and again. I've the O'Reilly code samples as well and I can't see where I'm going off. It's really frustrating.

Here's my Device.m:

@implementation Device

@synthesize udId, user, latitude, longitude;

- (CLLocationCoordinate2D)coordinate {
    CLLocationCoordinate2D internalCoordinate;

    internalCoordinate.latitude = [self.latitude doubleValue];
    internalCoordinate.longitude = [self.longitude doubleValue];

    return internalCoordinate;
}

- (NSString *)title {
    return self.user;
}

- (NSString *)subtitle {
    return nil;
}

- (id)initWithUDId:(NSString *)_udId User:(NSString *)_user Latitude:(NSNumber *)_latitude Longitude:(NSNumber *)_longitude {
    if (self == [super init]) {
        self.udId = _udId;
        self.user = _user;
        self.latitude = _latitude;
        self.longitude = _longitude;
    }

    return self;
}

- (void)dealloc {
    [udId release];
    self.udId = nil;

    [user release];
    self.user = nil;

    [latitude release];
    self.latitude = nil;

    [longitude release];
    self.longitude = nil;

    [super dealloc];
}

@end

And here's my DeviceMapAnnotator.m:

@implementation DeviceMapAnnotator

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
    if ([annotation isKindOfClass:[MKUserLocation class]]) {
        NSLog(@"annotation is an MKUserLocation class");

        return nil;
    }

    MKPinAnnotationView *deviceAnnotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"DeviceAnnotation"];

    if (deviceAnnotationView == nil) {
        deviceAnnotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"DeviceAnnotation"] autorelease];
        deviceAnnotationView.animatesDrop = NO;
        deviceAnnotationView.pinColor = MKPinAnnotationColorRed;
    }

    return deviceAnnotationView;
}

- (void)dealloc {
    [super dealloc];
}

@end

And here's the code calling it from my DashboardViewController.m:

- (void)updateMapAnnotations:(NSArray *)devices {
    for (Device *device in devices) {
        [map addAnnotation:device];
    }
}

And here's the code calling updateMapAnnotations from my app delegate:

- (void)requestFinished:(ASIHTTPRequest *)request {
    if (![request error]) {
        NSError *jsonError = nil;
        NSDictionary *jsonDictionary = [NSDictionary dictionaryWithJSONString:[request responseString] error:&jsonError];

        if (!jsonError || ([[jsonDictionary objectForKey:@"Success"] intValue] == 1)) {
            NSArray *jsonDevicesArray = [jsonDictionary objectForKey:@"Devices"];
            NSMutableArray *devicesArray = [[NSMutableArray alloc] initWithCapacity:[jsonDevicesArray count]];

            for (NSDictionary *deviceDictionary in jsonDevicesArray) {
                [devicesArray addObject:[[[Device alloc] initWithUDId:[deviceDictionary objectForKey:@"UDId"] User:[deviceDictionary objectForKey:@"User"] Latitude:[NSNumber numberWithDouble:[[deviceDictionary objectForKey:@"Latitude"] doubleValue]] Longitude:[NSNumber numberWithDouble:[[deviceDictionary objectForKey:@"Longitude"] doubleValue]]] autorelease]];
            }

            [dashboardViewController updateMapAnnotations:devicesArray];
        } else {
            //  AUTHORIZATION FAILED
        }
    }
}

I basically make a call to the server every 45 seconds, get a list of devices and their locations as a JSON string which is then deserialized into an NSArray containing Device objects. I then pass the array to updateMapAnnotations which then loops it and calls addAnnotation. The whole process works, and I guarantee that the objects being sent to DeviceMapAnnotator are of type Device, however the MKUserLocation check always returns prematurely and the whole process is just stopped dead in the water.

I would really appreciate it if someone who knows what they're doing with iOS/Objective-C, etc, can help me out (that's pretty much everyone because I apparently am an idiot).

Just to vent, I must say that Objective-C is getting on my $hit list really fast.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

陌生 2024-10-23 09:38:21

好吧,我已经成功了,尽管我不知道解决方案到底是什么。最后,我废弃了所有内容,并在一个新文件中从头开始重写,然后它就起作用了。我还意识到我没有在 JSON 中发回纬度和经度,但这仍然不是问题,因为它们无论如何都会被初始化为 0.0。最后我不知道是什么真正解决了这个问题,但它确实有效,所以我会接受它。

抱歉浪费了大家的时间。 :(

Okay, I got it to work, although I don't know exactly what the solution was. In the end I scrapped everything and rewrote it from scratch in a new file and it worked at that point. I also realized that I was not sending back the latitude and logitude in the JSON, however that still wasn't the problem because they would be initialized as 0.0 anyway. In the end I have no idea what really fixed it, but it works, so I'll take it.

Sorry to waste your guys' time. :(

铁轨上的流浪者 2024-10-23 09:38:21

我有类似的问题。显然,从地图视图中删除注释会导致它们的发布方式出现一些问题。注释掉代码修复了它。

- (void)dealloc {

//[mapView removeAnnotations:mapView.annotations];  

[super dealloc];

}

I had a similar problem. Apparently removing the annotations from the mapView causes some issues with how they are released. Commenting out the code fixed it.

- (void)dealloc {

//[mapView removeAnnotations:mapView.annotations];  

[super dealloc];

}

贩梦商人 2024-10-23 09:38:20

我也没有立即发现您的代码有任何问题。但是,您可以不直接测试注释,而是测试注释是否是 Device,而不是最初测试注释是否是 MKUserLocation,如下所示

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
    if ([annotation isKindOfClass:[Device class]]) {    
        MKPinAnnotationView *deviceAnnotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"DeviceAnnotation"];

        if (deviceAnnotationView == nil) {
             deviceAnnotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"DeviceAnnotation"] autorelease];
             deviceAnnotationView.animatesDrop = NO;
             deviceAnnotationView.pinColor = MKPinAnnotationColorRed;
        }

        return deviceAnnotationView;
    } else {
        NSLog(@"annotation is not a Device");

        return nil;
    }
}

:可能不是一个非常有用的建议,因为它基本上做了相同的事情,但也许以稍微不同的方式进行调试会在调试时产生不同的结果并导致真正的问题。

I am not immediately seeing any problem with your code either. However, instead of initially testing to see if the annotation is an MKUserLocation, you could instead not test for that directly and test whether the annotation is a Device, like so:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
    if ([annotation isKindOfClass:[Device class]]) {    
        MKPinAnnotationView *deviceAnnotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"DeviceAnnotation"];

        if (deviceAnnotationView == nil) {
             deviceAnnotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"DeviceAnnotation"] autorelease];
             deviceAnnotationView.animatesDrop = NO;
             deviceAnnotationView.pinColor = MKPinAnnotationColorRed;
        }

        return deviceAnnotationView;
    } else {
        NSLog(@"annotation is not a Device");

        return nil;
    }
}

This might not be a very helpful suggestion since it does basically the same thing, but maybe doing it a slightly different way will yield a different result when debugging and lead to the real problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文