plist에 저장하려는 사용자 지정 NSObject 클래스가 있습니다. 한 부분을 제외하고 올바르게 저장하고로드했습니다. 그뿐만 아니라 저장하려는 클래스에 사용자 지정 MKOverlay 클래스 개체가 있습니다. 부스러기가 NSCoding을 따르기 때문에 오류가 발생하지 않지만 앱을 저장하고 다시 연 후 오버레이가지도에 표시되지 않습니다. 빵 부스러기 객체는 0이 아니지만 여전히 표시되지 않습니다.NSCoder를 사용하여 사용자 지정 MKOverlay 저장
Trails.h
@interface Trails : NSObject <NSCoding>
{
@public
int topSpeed;
float avgSpeed;
}
@property (nonatomic, strong) NSString *miles;
@property (nonatomic, strong) NSDate *date;
@property (nonatomic, strong) NSString *time;
@property (nonatomic, strong) CrumbPath *crumbs;
- (NSString *)displayDate;
- (NSString *)displayStartTime;
- (void)addTopSpeed: (int)top withAvgSpeed:(float)avg;
@end
Trails.m
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:miles forKey:@"miles"];
[coder encodeObject:date forKey:@"date"];
[coder encodeObject:time forKey:@"time"];
[coder encodeObject:crumbs forKey:@"crumbs"];
[coder encodeFloat:avgSpeed forKey:@"avgSpeed"];
[coder encodeInt:topSpeed forKey:@"topSpeed"];
}
- (id)initWithCoder:(NSCoder *)coder {
self = [super init];
if(self != nil)
{
miles = [coder decodeObjectForKey:@"miles"];
date = [coder decodeObjectForKey:@"date"];
time = [coder decodeObjectForKey:@"time"];
crumbs = [coder decodeObjectForKey:@"crumbs"];
avgSpeed = [coder decodeFloatForKey:@"avgSpeed"];
topSpeed = [coder decodeIntForKey:@"topSpeed"];
}
return self;
}
Crumbs.h
@interface CrumbPath : NSObject <MKOverlay, NSCoding>
Crumbs.m
#import "CrumbPath.h"
#define INITIAL_POINT_SPACE 1000
#define MINIMUM_DELTA_METERS 10.0
@implementation CrumbPath
@synthesize points, pointCount;
- (id)initWithCenterCoordinate:(CLLocationCoordinate2D)coord
{
self = [super init];
if (self)
{
// initialize point storage and place this first coordinate in it
pointSpace = INITIAL_POINT_SPACE;
points = malloc(sizeof(MKMapPoint) * pointSpace);
points[0] = MKMapPointForCoordinate(coord);
pointCount = 1;
// bite off up to 1/4 of the world to draw into.
MKMapPoint origin = points[0];
origin.x -= MKMapSizeWorld.width/8.0;
origin.y -= MKMapSizeWorld.height/8.0;
MKMapSize size = MKMapSizeWorld;
size.width /= 4.0;
size.height /= 4.0;
boundingMapRect = (MKMapRect) { origin, size };
MKMapRect worldRect = MKMapRectMake(0, 0, MKMapSizeWorld.width, MKMapSizeWorld.height);
boundingMapRect = MKMapRectIntersection(boundingMapRect, worldRect);
// initialize read-write lock for drawing and updates
pthread_rwlock_init(&rwLock, NULL);
}
return self;
}
- (void)dealloc
{
free(points);
pthread_rwlock_destroy(&rwLock);
}
- (CLLocationCoordinate2D)coordinate
{
return MKCoordinateForMapPoint(points[0]);
}
- (MKMapRect)boundingMapRect
{
return boundingMapRect;
}
- (void)lockForReading
{
pthread_rwlock_rdlock(&rwLock);
}
- (void)unlockForReading
{
pthread_rwlock_unlock(&rwLock);
}
- (MKMapRect)addCoordinate:(CLLocationCoordinate2D)coord
{
// Acquire the write lock because we are going to be changing the list of points
pthread_rwlock_wrlock(&rwLock);
// Convert a CLLocationCoordinate2D to an MKMapPoint
MKMapPoint newPoint = MKMapPointForCoordinate(coord);
MKMapPoint prevPoint = points[pointCount - 1];
// Get the distance between this new point and the previous point.
CLLocationDistance metersApart = MKMetersBetweenMapPoints(newPoint, prevPoint);
MKMapRect updateRect = MKMapRectNull;
if (metersApart > MINIMUM_DELTA_METERS)
{
// Grow the points array if necessary
if (pointSpace == pointCount)
{
pointSpace *= 2;
points = realloc(points, sizeof(MKMapPoint) * pointSpace);
}
// Add the new point to the points array
points[pointCount] = newPoint;
pointCount++;
// Compute MKMapRect bounding prevPoint and newPoint
double minX = MIN(newPoint.x, prevPoint.x);
double minY = MIN(newPoint.y, prevPoint.y);
double maxX = MAX(newPoint.x, prevPoint.x);
double maxY = MAX(newPoint.y, prevPoint.y);
updateRect = MKMapRectMake(minX, minY, maxX - minX, maxY - minY);
}
pthread_rwlock_unlock(&rwLock);
return updateRect;
}
//Conform to NSCoding
- (void)encodeWithCoder:(NSCoder *)coder {
//I think I need to do something here?
}
- (id)initWithCoder:(NSCoder *)coder {
self = [super init];
if(self != nil)
{
//I think I need to do something here?
}
return self;
}
@end
을 당신이 어떤 데이터가없는/CrumbPath 클래스의 속성? 저장되는 것을 보지 마라. 나는 MKOverlay 프로토콜을 따르는 객체가'coordinate'와'boundingMapRect' 속성을 필요로한다고 생각했습니다. –
예, 각 파일의 전체 코드를 포함하지 않았으므로 전체 CrumbPath.m을 표시하도록 코드를 업데이트했습니다. – Glen