1、设计要求
传入一个txt格式的歌词文件,可以输出歌曲作者、名称和时间顺序的歌词内容。
LRCitem.h
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #d12f1b}p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px}p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo}p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #008400}p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px 'Heiti SC Light'; color: #008400}p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #bb2ca2}span.s1 {font-variant-ligatures: no-common-ligatures; color: #78492a}span.s2 {font-variant-ligatures: no-common-ligatures}span.s3 {font-variant-ligatures: no-common-ligatures; color: #bb2ca2}span.s4 {font-variant-ligatures: no-common-ligatures; color: #703daa}span.s5 {font-variant-ligatures: no-common-ligatures; color: #008400}span.s6 {font: 11.0px 'Heiti SC Light'; font-variant-ligatures: no-common-ligatures; color: #008400}span.s7 {font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures}span.s8 {font-variant-ligatures: no-common-ligatures; color: #4f8187}
#import <Foundation/Foundation.h>
@interface LRCitem : NSObject
{
float _lrcTime; //歌词时间点
NSString *_lrcString; //歌词
}
-(id)initWithLrcTime:(float)time andLrcString:(NSString *)lrcString;
//setter
-(void)setLrcTime:(float)time;
-(void)setLrcString:(NSString *)lrcString;
//getter
-(float)lrcTime;
-(NSString *)lrcString;
//排序规则:按照歌词时间排序
-(BOOL)isSortByTime:(LRCitem *)aItem;
-(void)printLrcItem;
@end
LrcManager.h
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px}p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo}p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px 'Heiti SC Light'; color: #008400}p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #bb2ca2}span.s1 {font-variant-ligatures: no-common-ligatures}span.s2 {font-variant-ligatures: no-common-ligatures; color: #bb2ca2}span.s3 {font-variant-ligatures: no-common-ligatures; color: #703daa}span.s4 {font-variant-ligatures: no-common-ligatures; color: #008400}span.s5 {font: 11.0px 'Heiti SC Light'; font-variant-ligatures: no-common-ligatures; color: #008400}span.s6 {font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures}
@interface LrcManager : NSObject
{
NSString *_title; //歌曲名
NSString *_auther; //歌手
NSMutableArray *_lrcList; //保存词条对象的数组
}
//构造方法,传入文件路径,初始化歌词管理器对象
-(id)initWithLrcFile:(NSString *)path;
-(void)showLrcItems; //遍历整个歌词文件
//给用户公开一个接口。输入时间,得到对应内容
+(void)userInterface;
@end
2、方法实现
LRCitem.m
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #d12f1b}p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px}p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #bb2ca2}p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo}p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #008400}p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #4f8187}p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px 'Heiti SC Light'; color: #008400}span.s1 {font-variant-ligatures: no-common-ligatures; color: #78492a}span.s2 {font-variant-ligatures: no-common-ligatures}span.s3 {font-variant-ligatures: no-common-ligatures; color: #000000}span.s4 {font-variant-ligatures: no-common-ligatures; color: #bb2ca2}span.s5 {font-variant-ligatures: no-common-ligatures; color: #703daa}span.s6 {font-variant-ligatures: no-common-ligatures; color: #3d1d81}span.s7 {font-variant-ligatures: no-common-ligatures; color: #4f8187}span.s8 {font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures}span.s9 {font-variant-ligatures: no-common-ligatures; color: #31595d}
#import "LRCitem.h"
@implementation LRCitem
-(id)initWithLrcTime:(float)time andLrcString:(NSString *)lrcString
{
self = [super init];
if (self) {
_lrcString=lrcString;
_lrcTime=time;
}
return self;
}
//setter
-(void)setLrcTime:(float)time
{
_lrcTime = time;
}
-(void)setLrcString:(NSString *)lrcString
{
_lrcString = lrcString;
}
//getter
-(float)lrcTime
{
return _lrcTime;
}
-(NSString *)lrcString
{
return _lrcString;
}
//排序规则
-(BOOL)isSortByTime:(LRCitem *)aItem
{
if ([self lrcTime] > [aItem lrcTime]) {
return YES;
}
else
return NO;
}
-(void)printLrcItem
{
NSLog(@"time is %.2f, lrc is %@", [self lrcTime], [self lrcString]);
}
@end
LrcManager.m
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #d12f1b}p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px}p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px 'Heiti SC Light'; color: #008400}p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #008400}p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo}p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #bb2ca2}p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #3d1d81}span.s1 {font-variant-ligatures: no-common-ligatures; color: #78492a}span.s2 {font-variant-ligatures: no-common-ligatures}span.s3 {font: 11.0px 'Heiti SC Light'; font-variant-ligatures: no-common-ligatures}span.s4 {font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures}span.s5 {font-variant-ligatures: no-common-ligatures; color: #bb2ca2}span.s6 {font-variant-ligatures: no-common-ligatures; color: #000000}span.s7 {font-variant-ligatures: no-common-ligatures; color: #4f8187}span.s8 {font-variant-ligatures: no-common-ligatures; color: #703daa}span.s9 {font-variant-ligatures: no-common-ligatures; color: #3d1d81}span.s10 {font-variant-ligatures: no-common-ligatures; color: #31595d}span.s11 {font-variant-ligatures: no-common-ligatures; color: #008400}span.s12 {font: 11.0px 'Heiti SC Light'; font-variant-ligatures: no-common-ligatures; color: #008400}span.s13 {font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #000000}span.s14 {font-variant-ligatures: no-common-ligatures; color: #d12f1b}span.s15 {font-variant-ligatures: no-common-ligatures; color: #272ad8}
#import "LrcManager.h"
#define LrcPath @"/Users/bear/Desktop/传奇歌词.txt"
//类扩展。可以给类扩展实例变量或者方法,可以实现实力变量和方法的私有化(不公开)
@interface LrcManager() //括号中不允许添加任何东西
-(BOOL)parseLrcFile:(NSString *)path;
-(void)parseLrcTitle:(NSString *)lineString;
-(void)parseLrcAuther:(NSString *)lineString;
-(void)parseLrcItem:(NSString *)lineString;
-(float)parseLrcTime:(NSString *)timeString;
@end
@implementation LrcManager
//构造方法,传入文件路径,初始化歌词管理器对象
-(id)initWithLrcFile:(NSString *)path
{
self = [super init];
if (self) {
_lrcList = [NSMutableArray array];
[self parseLrcFile:path]; //解析歌词文件
}
return self;
}
-(BOOL)parseLrcFile:(NSString *)path
{
NSString *fileContent = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
if (!fileContent) { //判断歌词文件是否读取成功
return NO;
}
//每行歌词都用换行进行了分割
NSArray *lineArray = [fileContent componentsSeparatedByString:@"\n"];
NSInteger lineCount = [lineArray count];
for (NSInteger i=0; i<lineCount; i++) { //可能行为空
NSString *lineString = [lineArray objectAtIndex:i]; //把每行分割出来
if([lineString isEqualToString:@""])
{
continue; //空行跳过
}
else if ([lineString hasPrefix:@"[ti:"]) //包含这个字符
{
//解析歌曲名
[self parseLrcTitle:lineString];
}
else if ([lineString hasPrefix:@"[ar:"]) {
//解析歌曲演唱者
[self parseLrcAuther:lineString];
}
else
{
//解析词条
[self parseLrcItem:lineString];
}
}
//对歌词的词条对象进行排序
[_lrcList sortUsingSelector:@selector(isSortByTime:)];
return YES;
}
//解析歌词标题的实现
-(void)parseLrcTitle:(NSString *)lineString
{
NSInteger len=[lineString length];
_title = [lineString substringWithRange:NSMakeRange(4, len-4-1)];
}
//解析歌曲作者
-(void)parseLrcAuther:(NSString *)lineString
{
NSInteger len=[lineString length];
_auther = [lineString substringWithRange:NSMakeRange(4, len-4-1)];
}
//解析歌词词条
-(void)parseLrcItem:(NSString *)lineString
{
NSArray *lrcArray = [lineString componentsSeparatedByString:@"]"];
NSInteger count = [lrcArray count];
for (NSInteger i=0; i<count-1; i++) {
LRCitem *item = [[LRCitem alloc] init];
//解析歌词时间
[item setLrcTime:[self parseLrcTime:[lrcArray objectAtIndex:i]]];
//设置歌词内容
[item setLrcString:[lrcArray lastObject]];
//把解析出来的歌词条添加到可变数组中
[_lrcList addObject:item];
}
}
//解析歌词时间的方法实现 [01:14.81
-(float)parseLrcTime:(NSString *)timeString
{
NSString *minString = [timeString substringWithRange:NSMakeRange(1, 2)];
NSString *secString = [timeString substringWithRange:NSMakeRange(4, 5)];
return ([minString intValue]*60+[secString floatValue]);
}
-(void)showLrcItems
{
for (LRCitem *item in _lrcList) {
[item printLrcItem];
}
}
//给用户公开一个接口。输入时间,得到对应内容
+(void)userInterface
{
LrcManager *manager = [[LrcManager alloc] initWithLrcFile:LrcPath];
[manager showLrcItems];
}
@end
3、需要注意的
在LrcManager.m文件中,我首次使用了类扩展的功能。
目前的理解就是,扩展的方法为这个类私有的。比如在本程序中,扩展的5个方法都是LrcManager私有的,这几个方法的声明和实现都写在了.m文件中,而没有写到.h文件中。所以,当别的类或者main函数import LrcManager.h文件时,也无法使用这几个类,所以叫做“私有”。
好处就是封装性。
还有一个问题是,这次的类设计比前几个都略复杂,明显感觉到不管是写.h文件的方法声明还是.m文件中的扩展方法,一开始想的都不全面,很可能在实现一个已经声明的方法时发现还需要添加一个新的方法,这就需要边写边添加。思路清晰很重要,弄清几个类之间的关系。
TODO
1、 类方法和对象方法的区别。
2、类扩展功能。