设计类-歌词解析类

1、设计要求

传入一个txt格式的歌词文件,可以输出歌曲作者、名称和时间顺序的歌词内容。


屏幕快照 2016-10-18 下午3.50.53.png
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、类扩展功能。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 174,676评论 25 709
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,301评论 4 61
  • 诗句封装在瓶子里 不再喝的烈酒 还有遗忘的星空 疲惫的眼睛 越是努力越看不清 黑夜里消失的月光 用什么来弥补 如何...
    yummy6阅读 211评论 0 0
  • 瓜藤 文/路人锋 一根攀援铁栅的瓜藤随风摇曳半空中秋慢慢蜗牛般爬上它宽阔的叶 西风飘摇了一夜一夜枝干被一只只秋悄悄...
    路人锋阅读 913评论 13 21
  • 早上起床老大说昨天蹲的屁股还疼,吃饭也没有坐下吃,我让他趴床上给他按了按,问题不大,可能就蹲了一下。上...
    502班赵梓旭阅读 211评论 0 0