我在名为Restaurant的NSManagedObject子类上有以下MKAnnotation协议实现:
接口:
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#import <MapKit/MapKit.h>
@interface Restaurant : NSManagedObject <MKAnnotation> {
CLLocationCoordinate2D coordinate;
}
@property (nonatomic, assign) CLLocationCoordinate2D primitiveCoordinate;
@property (nonatomic, copy) NSString * title;
@property (nonatomic, copy) NSString * subtitle;
@property (nonatomic, retain) NSNumber * longtitude;
@property (nonatomic, retain) NSNumber * latitude;
@end
实现:
#import "Restaurant.h"
@implementation Restaurant
@dynamic title;
@dynamic subtitle;
@dynamic coordinate;
@dynamic longtitude;
@dynamic latitude;
-(void)setCoordinate:(CLLocationCoordinate2D)newCoordinate{
[self willChangeValueForKey:@"coordinate"];
[self setPrimitiveCoordinate:newCoordinate];
[self didChangeValueForKey:@"coordinate"];
[self setValue:[NSNumber numberWithDouble:newCoordinate.latitude] forKey:@"latitude"];
[self setValue:[NSNumber numberWithDouble:newCoordinate.longitude] forKey:@"longtitude"];
}
-(CLLocationCoordinate2D)coordinate{
[self willAccessValueForKey:@"coordinate"];
CLLocationCoordinate2D temp = [self primitiveCoordinate];
[self didAccessValueForKey:@"coordinate"];
return temp;
}
-(void)setPrimitiveCoordinate:(CLLocationCoordinate2D)primitiveCoordinate{
coordinate = primitiveCoordinate;
}
-(CLLocationCoordinate2D)primitiveCoordinate{
return coordinate;
}
-(void)awakeFromFetch{
[super awakeFromFetch];
double longtitude = [[self longtitude] doubleValue];
double latitude = [[self latitude] doubleValue];
if(!isnan(longtitude) && !isnan(latitude)){
CLLocationCoordinate2D temp = CLLocationCoordinate2DMake(latitude, longtitude);
[self setPrimitiveCoordinate:temp];
}
}
@end
我跟着Apples Core Data programming guide关于非标准持久性属性和documentation of the MKAnnotation protocol来实现MKAnnotation的CLocation2DCoordinate
属性作为瞬态实例变量,因为Core Data不支持存储C结构。
我的问题是:这个实现是正确的还是你在我的实现中改变了什么?也许使用NSValue
来存储C结构而不是NSNumber
个对象(latitude
和longtitude
)?使用NSValue
代替哪些优点和缺点?其余的代码怎么样?
谢谢!
答案 0 :(得分:0)
将坐标作为瞬态实现的问题是,当设置纬度或经度时,将不会触发坐标KVO。因此,您最好将其实现为计算属性。您还缺少awakeFromSnapshotEvents
,当子上下文保存到没有更新过的经度或纬度的餐厅时,如果您没有keyPathsForValuesAffecting会自动为您完成此操作,则更新{@ 1}是必需的。
对于计算属性,它是:
// this means setting latitude or longitude causes coordinate KVO notification to be sent which the map is observing.
+ (NSSet<NSString *> *)keyPathsForValuesAffectingCoordinate
{
return [NSSet setWithObjects:@"latitude", @"longitude", nil];
}
- (CLLocationCoordinate2D)coordinate{
return CLLocationCoordinate2DMake(self.latitude, self.longitude);
}
- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate{
self.latitude = newCoordinate.latitude;
self.longitude = newCoordinate.longitude;
}
乍看之下,似乎setCoordinate发送过多通知存在问题,但是地图实际上在下一个runloop上更新了其注释视图,所以没关系。