Adding the date challenge: Warning possible spoiler alert!


#1

Here is my solution for the challenge of adding the date to our mapPoint annotation. It uses the subtitle attribute of the MKAnnotation to display the date. I don’t know if this is the best way or not but it works. I welcome all critique and feedback.

MapPoint.h

#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>

@interface MapPoint : NSObject <MKAnnotation>
{
    NSString *title;
    CLLocationCoordinate2D coordinate;
    NSString *subtitle;
}
// A new designated initializer for MapPoint Instances
- (id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t;

// This is a required property from MKAnnotation
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
// This is an optional property from MKAnnotation
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subtitle;
@end

MapPoint.m

#import "MapPoint.h"


@implementation MapPoint

@synthesize coordinate, title, subtitle;

- (id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t
{
    self = [super init];
    if (self) {
        // Initialization code here.
        coordinate = c;
        [self setTitle:t];

        // get the date and add it to subtitle.
        // create a date object
        NSDate *dateAdded = [NSDate date];
        // create a dateFormatter
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        // Set the format output
        [formatter setTimeStyle:NSDateFormatterNoStyle];
        [formatter setDateStyle:NSDateFormatterMediumStyle];
        // Need a string to stor the date into
        NSString *theString = [[NSString alloc] init];
        // put the formatted date into the string
        theString = [formatter stringFromDate:dateAdded];
        //NSLog(@"%@", theString);
        // set the subtitle
        [self setSubtitle:theString];

         // Cleanup all the objects
         //[theString release]; // this makes it crash :(
        [dateAdded release];
        [formatter release];
    }
    return self;
}
- (void) dealloc{
    [title release];
    [subtitle release];
    [super dealloc];
    
}

#2

Hi,

There are a couple of memory issues.

NSDate *dateAdded = [NSDate date];

returns an autoreleased date so the [dateAdded release] method is over-releasing it.

and

    NSString *theString = [[NSString alloc] init];

is creating a block of memory that you own and theString is pointing to that memory.

The next line
theString = [formatter stringFromDate:dateAdded];

is then changing theString to point to a new autoreleased NSString and so the earlier block of memory is now inaccessible and therefore a leak.

Gareth


#3

So should I skip the first alloc line and just use the second?


#4

Yes

and if you want to be really succinct you can remove dateAdded and theString

    [self setSubtitle:[formatter stringFromDate:[NSDate date]]];

Gareth


#5

Thanks for the excellent tip I will implement those changes.