- 01
 - 02
 - 03
 - 04
 - 05
 - 06
 - 07
 - 08
 - 09
 - 10
 - 11
 - 12
 - 13
 - 14
 - 15
 - 16
 - 17
 - 18
 - 19
 - 20
 - 21
 - 22
 
                        // Досталось по наследству:
@try {
    if([[items objectAtIndex:indexPath.row] performSelector:@selector(songsArray)]){
        NSArray *songsArray = [[items objectAtIndex:indexPath.row] songsArray];
        for(Song *song in songsArray){
            [song setIsSelected:button.selected];
        }
    }
 }
@catch (NSException *exception) {
    NSLog(@"need fix in next time");
}
// переделал в
if ( [[items objectAtIndex:indexPath.row] respondsToSelector:@selector(songsArray)] )
{
    NSArray *songsArray = [[items objectAtIndex:indexPath.row] songsArray];
    for(Song *song in songsArray){
         [song setIsSelected:button.selected];
    }
}
                                 
        
id fromSongArrayObj = [items objectAtIndex:indexPath.row];
NSArray *songsArray = [fromSongArrayObj songsArray];
for(Song *song in songsArray) {
[song setIsSelected:button.selected];
}
}
Если id не поддерживает метод songsArray, то переменная songsArray в данном случае будет nil и цикл просто не выполнится. Можно еще if повесить, чтобы прологировать данный момент. Вот это я бы назвал более-менее нормально переделанный код.