Проблемы с быстрым перечислением в Objective C

Я пытаюсь использовать быстрое перечисление для печати всех песен, которые есть в списке воспроизведения, но, похоже, я делаю это неправильно. Может ли кто-нибудь помочь мне? Я определил класс Song следующим образом:

@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 выглядит так:

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

а теперь к классу PlayList:

@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

Может кто-нибудь объяснить мне, почему мой код не работает?
И какой метод displayPlaylist лучше?


person nemesis    schedule 04.03.2012    source источник
comment
Что значит не работает? Уточните, пожалуйста, ожидаемые и фактические результаты.   -  person jscs    schedule 05.03.2012


Ответы (2)


Вы никогда не создаете плейлист

в классе Playlist добавьте playlist = [[NSMutableArray alloc] init] ;

И рассмотрите возможность использования свойства для плейлиста (блин, похожие имена довольно раздражают!)

Если вы не хотите иметь инициализацию, вы также можете сделать:

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

ответ на второй вопрос: это зависит

  • если вы знаете, что в массиве только экземпляры Song, то второй вариант лучше, так как немного быстрее

  • если вы не знаете, это первое, так как в противном случае объект получит сообщение, он не может обработать -> сбой

  • или вы можете сделать

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

    если вы хотите быть уверены, что сообщение будет понято, независимо от того, какой это объект.

person vikingosegundo    schedule 04.03.2012
comment
:D Это моя догадка и о настоящей беде! (Сколько раз это повторяется в неделю?) - person jscs; 05.03.2012
comment
больше чем единожды. Но это и понятно, так как отправка сообщения на nil не является ошибкой. - person vikingosegundo; 05.03.2012
comment
Спасибо за быстрый ответ, не заметил :) - person nemesis; 05.03.2012
comment
Что вы имеете в виду, рассматривая недвижимость для плейлиста? - person nemesis; 05.03.2012
comment
Я предпочитаю использовать свойства вместо простых членов. в этом случае я бы, вероятно, выбрал частное свойство, объявленное в расширении класса - person vikingosegundo; 05.03.2012
comment
Когда я пытаюсь использовать свойства, я могу не получить доступ к элементу. Например, если я объявил имя списка воспроизведения как @property (nonatomic,strong) NSString *playlist (а затем синтезировал его), как мне отобразить имя в методе класса PlayList? с [имя себя] ? Если да, то он говорит мне, что есть EXC_BAD_ACCESS. Кроме того, как объявить NSMutableArray с помощью свойства? И в чем разница между объявлением элементов как свойств или их объявлением в разделе интерфейса между { и }? - person nemesis; 05.03.2012
comment
Извините, но это принципиальные вопросы, на которые просто невозможно ответить в комментариях. пожалуйста, ознакомьтесь со свойствами, проверив некоторые ресурсы. Я собрал некоторые здесь: stackoverflow .com/questions/4539990/ Если у вас остались вопросы, вернитесь и задайте новый, более точный вопрос. - person vikingosegundo; 05.03.2012
comment
Я обязательно буду, но теперь, когда ARC реализован в XCode, стоит ли руководство по управлению памятью iOS? Спасибо за ссылку. - person nemesis; 05.03.2012
comment
даже с ARC вам нужно знать правила управления, так как ARC зависит от него и предполагает, что вы придерживаетесь соглашений об именах и тому подобного. Правила управления по-прежнему необходимо читать (и необходимо понимать) - person vikingosegundo; 05.03.2012
comment
ARC — отличный инструмент, но если вы нацелитесь на свою ногу, он снесет вам обе ноги. - person vikingosegundo; 05.03.2012
comment
=) хорошо! действительно, спасибо за ссылку! Я чувствую, что найду там много ценной информации. - person nemesis; 05.03.2012

Похоже, вы не инициализируете свой массив плейлистов. Вы можете делать это лениво в своих методах, проверяя nil или переопределяя метод init для вашего класса PlayList.

person Jon Shier    schedule 04.03.2012