0

I am trying to use fast enumeration to print all songs that are in a playlist, but it seems like I am doing it wrong. Could someone help me out? I have defined a Song class like this :

@interface Song : NSObject
@property (nonatomic,strong) NSString *title;
@property (nonatomic,strong) NSString *artist;
@property (nonatomic,strong) NSString *album;
@property (nonatomic,strong) NSString *playtime;
-(void) displaySong;
@end

displaySong function looks like this :

-(void) displaySong {
NSLog(@"%@ - %@ [%@] - %@\n", artist, title, album, playtime);
}

and now, to the PlayList class :

@interface PlayList : NSObject{
NSString *name;
NSMutableArray *playlist;
}
-(void) addSongToPlaylist: (Song *) song;
-(void) displayPlaylist;
@end

@implementation PlayList
-(void) addSongToPlaylist: (Song *) nameOfSong{
    [playlist addObject:nameOfSong];
}

-(void) displayPlaylist{
NSLog(@"Playlist called %@:\n", name);
for(id obj in playlist)
{
    if([obj isKindOfClass:[Song class]])
    [obj displaySong];
}
}

// I also tried the displayPlaylist method this way, but it wasn't working either
-(void) displayPlaylist{
NSLog(@"Playlist called %@:\n", name);
for(Song *song in playlist)
{
    [song displaySong];
}

@end

Could somebody please explain to me why my code isn't working?
And what displayPlaylist method is better?

vikingosegundo
  • 52,040
  • 14
  • 137
  • 178
nemesis
  • 1,349
  • 1
  • 15
  • 30
  • What does "isn't working" mean? Please be more explicit about your expected and actual results. – jscs Mar 04 '12 at 22:19

2 Answers2

3

You are never creating playlist

in the Playlist class' init add a playlist = [[NSMutableArray alloc] init] ;

And consider using a property for playlist (man — the similar names are quite annoying!)

If you don't want to have a init, you also can do:

-(void) addSongToPlaylist: (Song *) nameOfSong{
    if(!playlist)
        playlist= [[NSMutableArray alloc] init];
    [playlist addObject:nameOfSong];
}

to answer the second question: it depends

  • if you know, that there are only instances of Song in the array, the second version is better, as a bit faster

  • if you don't know, it is the first, as otherwise a object would receive a message, it can't handle -> crash

  • or you can do

    for(id obj in playlist)
    {
        if([obj respondsToSelector:@selector(displaySong)])
        [obj displaySong];
    }
    

    if you wants to be sure, that the message is understood, no matter what object it is.

vikingosegundo
  • 52,040
  • 14
  • 137
  • 178
  • :D This is my guess as to the actual trouble as well! (How many times does this come up in a week?) – jscs Mar 04 '12 at 22:21
  • more than once. But it is understandable, as sending a message to nil isn't an error. – vikingosegundo Mar 04 '12 at 22:26
  • Thanks for the quick reply, I didn't notice it :) – nemesis Mar 04 '12 at 22:26
  • What do you mean by considering a property for playlist? – nemesis Mar 05 '12 at 12:15
  • I prefer to use properties instead of plain members. in this case, I would probably go with an private property, declared in a class extension – vikingosegundo Mar 05 '12 at 12:19
  • When I'm trying to use properties I may fail to access the member. For instance, if I've declared the name of the playlist as @property (nonatomic,strong) NSString *playlist (and then synthesize it), how do I display the name in a method of PlayList class? with [self name] ? If yes, then it's telling me that there is an EXC_BAD_ACCESS. Also, how to declare an NSMutableArray using property? And what's the difference between declaring elements as properties or declaring them in the interface section between { and } ? – nemesis Mar 05 '12 at 13:15
  • Sorry, but this are fundamental questions, that just cannot be answered in comments. please familiarize yourself with properties by checking some resources. I collected some here: http://stackoverflow.com/questions/4539990/ios-sdk-first-advice-for-beginners/4540136#4540136 If you have questions left than, come back and ask a new, more precise question. – vikingosegundo Mar 05 '12 at 13:24
  • I sure will, but now, that ARC is implemented in XCode, is iOS Memory Management Guide worth it? Thanks for the link. – nemesis Mar 05 '12 at 13:36
  • even with ARC you need to know the management rules, as ARC depends on it and assumes, that you stick to the naming conventions and stuff like this. The management rules is still a must-read (and must-understand) – vikingosegundo Mar 05 '12 at 13:38
  • ARC is a great tool, but if you aim at your foot, it will blow away both your legs. – vikingosegundo Mar 05 '12 at 13:40
  • =) ok! really, thanks for the link! I feel like I'm going to find a lot of precious information there. – nemesis Mar 05 '12 at 13:43
1

You don't appear to be initializing your playlist array. You can do so lazily in your methods by checking for nil or by overriding the init method for your PlayList class.

Jon Shier
  • 12,200
  • 3
  • 35
  • 37