前言及题目:
最近在学OC框架,学到了字典和数组,于是写了一道练习题,这道题从语法角度来说并不难,但是逻辑和类的设计上麻烦一些。可能因为我是小白的原因吧!在这里把这个代码记录下来,因为我写了两个小时吧,从拿到题目开始构思到完成。
题目: 定义三个新类,分别名为Song、PlayList和MusicCollection。Song对象包含着关于特定歌曲的信息,比如歌曲名、艺术家、专辑、歌曲长度等;PlayList对象包含播放列表名称和一个歌曲的集合;MusicConllection对象包含播放列表集合,它包括一个名为Library的主播放列表,这个列表包含该集合中的所有歌曲。定义上述的三个类,并编写方法实现下列任务:
//• 创建一个Song对象,并设置其信息。
//• 创建一个PlayList对象,并对播放列表添加和删除歌曲。如果一首新歌不在主列表中,那么将其添加进去。确保从主播放列表中删除一首歌时,也要从音乐集合中的其他播放列表删除此歌曲。
//• 创建一个MusicCollection对象,并对该集合添加和删除播放列表。
//• 搜索并显示关于所有歌曲、播放列表或整个音乐集合的信息。
代码及程序结构:
main.m:
#import <Foundation/Foundation.h>
#import "Song.h"
#import "PlayList.h"
#import "MusicConllection.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
// MusicCollection
MusicConllection *musicCollection=[[MusicConllection alloc] init];
// 歌曲数组
NSArray *songArray=[NSArray array];
// 添加歌曲
for (int i=0; i<5; i++) {
// 输入歌名
char *name=malloc(30*sizeof(char));
NSLog(@"输入song%i的歌名:",i);
gets(name);
NSString *nameStr=[NSString stringWithUTF8String:name];
// 输入艺术家
char *artist=malloc(20*sizeof(char));
NSLog(@"输入song%i的艺术家:",i);
gets(artist);
NSString *artistStr=[NSString stringWithUTF8String:artist];
// 输入专辑
char *album=malloc(30*sizeof(char));
NSLog(@"输入song%i的专辑:",i);
gets(album);
NSString *albumStr=[NSString stringWithUTF8String:album];
// 输入歌曲长度
int length;
NSLog(@"输入song%i的长度:",i);
scanf("%d",&length);
getchar();
// song
Song *song=[[Song alloc] initWithName:nameStr andArtist:artistStr andAlbum:albumStr andLength:length];
// songArray
songArray=[songArray arrayByAddingObject:song];
}
// PlayList1
PlayList *playList1=[[PlayList alloc] initWithListName:@"playList1"];
// PlayList2
PlayList *playList2=[[PlayList alloc] initWithListName:@"playList2"];
// 把0,1,2这三首歌曲放到歌曲列表1,把3,4两首歌放到歌曲列表2
if ([musicCollection addList:playList1]&&[musicCollection addList:playList2]) {
for (int i=0; i<3; i++) {
// 添加歌曲到列表1
[musicCollection addSongToList:songArray[i] andListName:playList1.listName];
}
for (int i=3; i<5; i++) {
// 添加歌曲到列表2
[musicCollection addSongToList:songArray[i] andListName:playList2.listName];
}
// 打印列表1
NSLog(@"%@",[[[musicCollection collection] objectForKey:playList1.listName] songList]);
// 打印列表2
NSLog(@"%@",[[[musicCollection collection] objectForKey:playList2.listName] songList]);
// 打印主列表
NSLog(@"%@",[[musicCollection collection] objectForKey:@"mainPlayList"]);
for (int i=0; i<3; i++) {
// 从列表1中删除歌曲
[musicCollection removeSongFromList:[songArray[i] name] andListName:playList1.listName];
}
for (int i=3; i<5; i++) {
// 从主列表中删除歌曲
[musicCollection removeSongFromMainList:[songArray[i]name]];
}
// 删除列表1
[musicCollection removeList:playList1.listName];
// 删除列表2
[musicCollection removeList:playList2.listName];
}
}
return 0;
}
Song.h
//Song对象包含着关于特定歌曲的信息,比如歌曲名、艺术家、专辑、歌曲长度等;
#import <Foundation/Foundation.h>
@interface Song : NSObject
@property NSString* name;//歌名
@property NSString* artist;//艺术家
@property NSString* album;//专辑
@property float length;//歌曲长度
//在构造函数中完成歌曲信息设置
-(id)initWithName:(NSString *)name andArtist:(NSString*) artist andAlbum:(NSString *)album andLength:(float) length;
@end
Song.m
#import "Song.h"
@implementation Song
//构造,完成歌曲初始化
-(id)initWithName:(NSString *)name andArtist:(NSString *)artist andAlbum:(NSString *)album andLength:(float)length{
if (self=[super init]) {
_name=name;
_artist=artist;
_album=album;
_length=length;
}
return self;
}
//查询
-(NSString *)description{
NSMutableString *str=[[NSMutableString alloc] init];
[str appendString:@"{\n"];
[str appendFormat:@"\t歌名:%@,艺术家:%@,专辑:%@,长度:%g\n",_name,_artist,_album,_length];
[str appendFormat:@"}\n"];
return str;
}
@end
PlayList.h
//PlayList对象包含播放列表名称和一个歌曲的集合;
#import <Foundation/Foundation.h>
#import "Song.h"
@interface PlayList : NSObject
@property NSString* listName;//播放列表名称
@property NSMutableDictionary *songList;//播放列表内容,是一个动态字典,里面存放song对象
-(id)initWithListName:(NSString*)listName;//创建歌曲列表,初始化列表名
-(BOOL)addSong:(Song*)song;//添加歌曲,返回操作是否成功
-(BOOL)removeSong:(NSString*)songName;//删除歌曲,返回操作是否成功
@end
PlayList.m
#import "PlayList.h"
@implementation PlayList
//构造,完成列表初始化
-(id)initWithListName:(NSString *)listName{
if (self=[super init]) {
_listName=listName;
// 创建歌曲列表内容对象,之后添加删除操作都针对该内容对象
NSMutableDictionary *songList=[NSMutableDictionary dictionaryWithCapacity:100];
_songList=songList;
}
return self;
}
//添加歌曲
-(BOOL)addSong:(Song *)song{
// 先检查本列表中是否已经包含该歌曲,如果包含则返回NO,表示操作失败
// 否则添加并返回YES
if ([[_songList allKeys] containsObject:song.name]) {//如果包含
return NO;
}else{
[_songList setObject:song forKey:song.name];//向本列表添加
return YES;
}
}
//删除歌曲
-(BOOL)removeSong:(NSString *)songName{
// 先检查本列表中是否包含该歌曲,如果包含则返回NO,表示操作失败
// 否则添加并返回YES
if ([[_songList allKeys] containsObject:songName]) {//如果包含
[_songList removeObjectForKey:songName];
return YES;
}else{
return NO;
}
}
//查询
-(NSString *)description{
NSMutableString *str=[[NSMutableString alloc] init];
[str appendFormat:@"%@:{\n",_listName];
for (id key in _songList) {
[str appendFormat:@"\t%@,",[[_songList objectForKey:key] name]];
}
[str appendFormat:@"}\n"];
return str;
}
@end
MusicConllection.h
//MusicConllection对象包含播放列表集合,它包括一个名为Library的主播放列表,这个列表包含该集合中的所有歌曲。
#import <Foundation/Foundation.h>
#import "PlayList.h"
#import "Song.h"
@interface MusicConllection : NSObject
@property NSMutableDictionary *collection;//播放列表集合内容,里面要包括一个主播放列表还有其他播放列表
-(id)init;
-(BOOL)addSongToList:(Song*)song andListName:(NSString *)listName;//添加歌曲到指定列表
-(BOOL)removeSongFromList:(NSString*)songName andListName:(NSString*)listName;//从指定列表删除歌曲
-(BOOL)removeSongFromMainList:(NSString*)songName;//从主播放列表中删除歌曲
-(BOOL)addList:(PlayList*)newPlayList;//向音乐集合中添加播放列表
-(BOOL)removeList:(NSString*)playListName;//从音乐集合中删除播放列表
@end
MusicConllection.m
#import "MusicConllection.h"
@implementation MusicConllection
//构造函数完成初始化
-(id)init{
if (self=[super init]) {
// 创建播放列表集合
NSMutableDictionary *collection=[NSMutableDictionary dictionaryWithCapacity:100];
// 创建一个主播放列表
PlayList *mainPlayList=[[PlayList alloc] initWithListName:@"mainPlayList"];
// 将主播放列表添加到播放列表集合当中
[collection setObject:mainPlayList forKey:mainPlayList.listName];
// 将刚刚创建的collection赋给成员变量播放列表内容对象
_collection=collection;
}
return self;
}
//添加歌曲到指定列表中,添加完成之后要查看主列表中是否有
-(BOOL)addSongToList:(Song *)song andListName:(NSString *)listName{
if ([[_collection objectForKey:listName] addSong:song]) {//指定列表添加成功
NSLog(@"向列表%@添加%@成功",listName,song.name);
if (![[[[_collection objectForKey:@"mainPlayList"] songList]allKeys]containsObject:song.name]) {//主列表中不包含
NSLog(@"主列表中不包含该歌曲");
// 往主列表中添加
[[[_collection objectForKey:@"mainPlayList"] songList]setObject:song forKey:song.name];
NSLog(@"主列表中添加%@成功",song.name);
}
return YES;
}else{
NSLog(@"向列表%@添加%@失败",listName,song.name);
return NO;
}
}
//从指定列表中删除歌曲,删除完成后要查看其他列表中是否也含有该歌曲,如果没有就要从主列表中删除该首歌
-(BOOL)removeSongFromList:(NSString *)songName andListName:(NSString *)listName{
int tag=0;
if ([[_collection objectForKey:listName] removeSong:songName]) {//指定列表删除成功
// 遍历collection中的列表,看除了main是否还有列表中含有该歌曲
NSEnumerator *enu=[_collection keyEnumerator];
id key;
while (key=[enu nextObject]) {
if (![key isEqualToString:@"mainPlayList"]&&[[[[_collection objectForKey:key] songList]allKeys]containsObject:songName])
{//非主列表包含song
tag=1;
break;
}
}
// 判断
if (tag==0) {//其他列表不包含这首歌,主列表删除
[[_collection objectForKey:@"mainPlayList"] removeSong:songName];
}
NSLog(@"从指定列表%@中删除%@成功",listName,songName);
return YES;
}else{
NSLog(@"指定列表%@中没有%@,删除失败",listName,songName);
return NO;
}
}
//向集合中添加播放列表
-(BOOL)addList:(PlayList *)newPlayList{
if ([[_collection allKeys] containsObject:newPlayList.listName]) {//已经有该列表
NSLog(@"集合中已经有%@,添加失败",newPlayList.listName);
return NO;
}else{//添加
[_collection setObject:newPlayList forKey:newPlayList.listName];
NSLog(@"向集合中添加%@成功",newPlayList.listName);
return YES;
}
}
//从集合中删除播放列表
-(BOOL)removeList:(NSString *)playListName{
if (![[_collection allKeys] containsObject:playListName]||[playListName isEqualToString:@"mainPlayList"]) {//没有该列表或者想要删除主列表,失败
NSLog(@"集合中没有%@,删除失败",playListName);
return NO;
}else{
[_collection removeObjectForKey:playListName];
NSLog(@"集合中删除%@成功",playListName);
return YES;
}
}
//从主播放列表中删除歌曲
-(BOOL)removeSongFromMainList:(NSString *)songName{
if (![[[[_collection objectForKey:@"mainPlayList"] songList]allKeys]containsObject:songName]) {//主列表不包含
NSLog(@"主列表中不包含%@,删除失败",songName);
return NO;
}else{
[[_collection objectForKey:@"mainPlayList"]removeSong:songName];//删除
// 遍历,查找其他列表中没有被删除的对应歌曲
NSEnumerator *enu=[_collection keyEnumerator];
id key;
while (key=[enu nextObject]) {
if ([[[[_collection objectForKey:key] songList]allKeys]containsObject:songName])
{
[[_collection objectForKey:key] removeSong:songName];
}
}
NSLog(@"从主列表中删除%@成功",songName);
return YES;
}
}
//查询
-(NSString *)description{
NSMutableString *str=[[NSMutableString alloc] init];
[str appendFormat:@"collection:{/n"];
for (id key in _collection) {
[str appendFormat:@"\t%@,",key];
}
[str appendFormat:@"}\n"];
return str;
}
@end
NSMutableDictionary+show.h
//
// NSMutableDictionary+show.h
// OC-Foundation4
//
// Created by mac on 15/10/14.
// Copyright (c) 2015年 macb. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSMutableDictionary (show)
@end
NSMutableDictionary+show.m
//
// NSMutableDictionary+show.m
// OC-Foundation4
//
// Created by mac on 15/10/14.
// Copyright (c) 2015年 macb. All rights reserved.
//
#import "NSMutableDictionary+show.h"
@implementation NSMutableDictionary (show)
-(NSString *)descriptionWithLocale:(id)locale{
NSMutableString *mulStr=[NSMutableString string];
[mulStr appendString:@"{\n"];
for (id key in self)//self指的是当前调用的字典
{
[mulStr appendFormat:@"\t%@ = %@;\n",key,[self objectForKey:key]];
}
[mulStr appendString:@"}"];
return mulStr;
}
@end
运行: