OC基础--字符串
前言
做iOS开发有3年了,从当初的小白到现在,断断续续看过很多资料,之前也写过一些博文来记录,但是感觉知识点都比较凌乱。所以最近准备抽时间把iOS开发的相关知识进行一个梳理,主要分为OC基础、UI控件、多线程、动画、网络、数据持久化、自动布局、第三方框架等几个模块进行梳理。本系列的所有博文集合参见:iOS开发知识梳理博文集。本文主要介绍 OC基础--字符串。
字符串应该是我们开发过程中用的最多的一种数据类型了,一般与后台的请求交互都跟字符串有关,不管是json串还是其他的数据格式,后台提供的绝大部分数据都是以字符串的形式返回的。Objective-C里核心的处理字符串的类就是NSString和NSMutableString这两个类,这两个类完成了Objective-C中字符串大部分功能的处理,我们今天的重点就是这两个类了。(后面内容转载自:玩转 NSString)
一 NSString
1.1 字符串属性
//////////字符串属性//////////
NSString *str1 = @"string"; NSLog(@"长度: %ld", str1.length);
NSLog(@"描述: %@", str1.description);
NSLog(@"哈希地址: %lu", (unsigned long)str1.hash);
NSLog(@"字符串对应下标字符: %c", [str1 characterAtIndex:]);
//输出: 长度: 6
//输出: 描述: string
//输出: 哈希地址: 10152471993823965
//输出: 字符串对应下标字符: r
1.2 字符串截取
//截取指定位置之后的字符串
- (NSString *)substringFromIndex:(NSUInteger)from;
//从0下标开始截取到指定位置的字符串
- (NSString *)substringToIndex:(NSUInteger)to;
//截取指定范围的字符串
- (NSString *)substringWithRange:(NSRange)range;
//截取字符串指定范围的字符
- (void)getCharacters:(unichar *)buffer range:(NSRange)range;
1.3 字符串比较
将两个字符串进行计较,返回NSComparisonResult枚举结果。
//////////字符串比较//////////
//1.比较
- (NSComparisonResult)compare:(NSString *)string;
//2.比较(指定字符串,条件)
- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask;
//3.比较(指定字符串,条件,范围)
- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange;
//4.比较(指定字符串,条件,范围,本地化)
- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange locale:(nullable id)locale;
//5.比较(不区分大小写)
- (NSComparisonResult)caseInsensitiveCompare:(NSString *)string; //6.本地化比较
- (NSComparisonResult)localizedCompare:(NSString *)string;
//7.本地化比较(不区分大小写)
- (NSComparisonResult)localizedCaseInsensitiveCompare:(NSString *)string;
//8.本地化比较(标准)
- (NSComparisonResult)localizedStandardCompare:(NSString *)string; //9.判断两个字符串是否内容一致
- (BOOL)isEqualToString:(NSString *)aString;
比较结果说明:
| NSComparisonResult | 说明 | 
|---|---|
| NSOrderedAscending | 升序 (左小右大) | 
| NSOrderedSame | 相同 (内容相同) | 
| NSOrderedDescending | 降序 (左大右小) | 
比较选项说明:
| NSStringCompareOptions | 说明 | 
|---|---|
| NSCaseInsensitiveSearch | 不区分大小写比较 | 
| NSLiteralSearch | 区分大小写比较 | 
| NSBackwardsSearch | 从字符串末尾开始搜索 | 
| NSAnchoredSearch | 搜索限制范围的字符串 | 
| NSNumericSearch | 按照字符串里的数字为依据,算出顺序 | 
| NSDiacriticInsensitiveSearch | 忽略 "-" 符号的比较 | 
| NSWidthInsensitiveSearch | 忽略字符串的长度,比较出结果 | 
| NSForcedOrderingSearch | 忽略不区分大小写比较的选项 | 
| NSRegularExpressionSearch | 只能应用于 rangeOfString:..., stringByReplacingOccurrencesOfString:...和 replaceOccurrencesOfString:...方法 | 
1.4 字符串搜索
//////////搜索基本//////////
//1.是否包含前缀(以str开头)
- (BOOL)hasPrefix:(NSString *)str;
//2.是否包含后缀(以str结尾)
- (BOOL)hasSuffix:(NSString *)str;
//3.获取公共前缀
- (NSString *)commonPrefixWithString:(NSString *)str options:(NSStringCompareOptions)mask;
//4.是否包含字符串
- (BOOL)containsString:(NSString *)str;
//5.本地化是否包含字符串(不区分大小写)
- (BOOL)localizedCaseInsensitiveContainsString:(NSString *)str;
//6.本地化是否包含字符串(标准)
- (BOOL)localizedStandardContainsString:(NSString *)str;
//7.本地化搜索字符串范围(标准)
- (NSRange)localizedStandardRangeOfString:(NSString *)str; //////////搜索字符串//////////
//8.搜索(指定字符串)
- (NSRange)rangeOfString:(NSString *)searchString;
//9.搜索(指定字符串,条件)
- (NSRange)rangeOfString:(NSString *)searchString options:(NSStringCompareOptions)mask;
//10.搜索(指定字符串,条件,范围)
- (NSRange)rangeOfString:(NSString *)searchString options:(NSStringCompareOptions)mask range:(NSRange)searchRange;
//11.搜索(指定字符串,条件,范围,本地化)
- (NSRange)rangeOfString:(NSString *)searchString options:(NSStringCompareOptions)mask range:(NSRange)searchRange locale:(nullable NSLocale *)locale; //////////搜索字符集合//////////
//12.搜索(指定字符集合)
- (NSRange)rangeOfCharacterFromSet:(NSCharacterSet *)searchSet;
//13.搜索(指定字符集合,条件)
- (NSRange)rangeOfCharacterFromSet:(NSCharacterSet *)searchSet options:(NSStringCompareOptions)mask;
//14.搜索(指定字符集合,条件,范围)
- (NSRange)rangeOfCharacterFromSet:(NSCharacterSet *)searchSet options:(NSStringCompareOptions)mask range:(NSRange)searchRange; //15.用字符串的字符编码指定索引查找位置
- (NSRange)rangeOfComposedCharacterSequenceAtIndex:(NSUInteger)index;
//16.用字符串的字符编码指定区域段查找位置
- (NSRange)rangeOfComposedCharacterSequencesForRange:(NSRange)range;
1.5 字符串拼接
//////////字符串拼接//////////
NSString *string = @"";
NSString *appStr = @"";
NSString *resultStr1 = [string stringByAppendingString:appStr];
NSString *resultStr2 = [string stringByAppendingFormat:@" + %@", appStr]; NSLog(@"普通拼接: %@", resultStr1);
NSLog(@"格式化拼接: %@", resultStr2);
//输出: 普通拼接: 12
//输出: 格式化拼接: 1 + 2
1.6 字符串基本类型转换
//////////字符串基本类型转换//////////
NSString *numStr = @"87234.2345"; NSLog(@"double型: %f", numStr.doubleValue);
NSLog(@"float型: %f", numStr.floatValue);
NSLog(@"int型: %d", numStr.intValue);
NSLog(@"NSInteger型: %ld", numStr.integerValue);
NSLog(@"long long型: %lld", numStr.longLongValue);
NSLog(@"BOOL型: %d", numStr.boolValue);
//输出: double型: 87234.234500
//输出: float型: 87234.234375
//输出: int型: 87234
//输出: NSInteger型: 87234
//输出: long long型: 87234
//输出: BOOL型: 1
1.7 字符串大小写转换
//////////字符串大小写转换//////////
NSString *string = @"string"; NSLog(@"大写: %@", string.uppercaseString);
NSLog(@"小写: %@", string.lowercaseString);
NSLog(@"首字母大写: %@", string.capitalizedString);
//输出: 大写: STRING
//输出: 小写: string
//输出: 首字母大写: String //本地化(大写)
- (NSString *)uppercaseStringWithLocale:(nullable NSLocale *)locale;
//本地化(小写)
- (NSString *)lowercaseStringWithLocale:(nullable NSLocale *)locale;
//本地化(首字母大写)
- (NSString *)capitalizedStringWithLocale:(nullable NSLocale *)locale;
1.8 字符串分行,分段
//////////分行//////////
//1.指定范围,分行取字符串
- (void)getLineStart:(nullable NSUInteger *)startPtr end:(nullable NSUInteger *)lineEndPtr contentsEnd:(nullable NSUInteger *)contentsEndPtr forRange:(NSRange)range;
//2.获取指定范围该行的范围
- (NSRange)lineRangeForRange:(NSRange)range; //////////分段//////////
//3.指定范围,分段取字符串
- (void)getParagraphStart:(nullable NSUInteger *)startPtr end:(nullable NSUInteger *)parEndPtr contentsEnd:(nullable NSUInteger *)contentsEndPtr forRange:(NSRange)range;
//4.获取指定范围该段落的范围
- (NSRange)paragraphRangeForRange:(NSRange)range; //////////字符串分行,分段//////////
NSString *string = @"123 456\nABC,DEF\nabc.def";
//获取该行的范围(指定范围)
NSRange range1 = [string lineRangeForRange:NSMakeRange(, )];
NSLog(@"%ld 行长度: %ld", range1.location, range1.length);
//输出: 0 行长度: 16 //获取该段落范围(指定范围)
NSRange range2 = [string paragraphRangeForRange:NSMakeRange(, )];
NSLog(@"%ld 段落长度: %ld", range2.location, range2.length);
//输出: 0 段落长度: 8
1.9 字符串列举(按条件)
//////////字符串列举//////////
NSString *string = @"123456\nABCDEF\nabcdef
//1.列举(按行)
[string enumerateLinesUsingBlock:^(NSString * _Nonnull line, BOOL * _Nonnull stop) {
NSLog(@"每行: %@", line);
}];
//输出: 每行: 123456
//输出: 每行: ABCDEF
//输出: 每行: abcdef //2.列举(范围,条件)
[string enumerateSubstringsInRange:NSMakeRange(5, 10) options:NSStringEnumerationByLines usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) { NSLog(@"%@", substring);
NSLog(@"%ld %ld", substringRange.location, substringRange.length);
NSLog(@"%ld %ld", enclosingRange.location, enclosingRange.length); }];
//输出: 6
//输出: 5 1
//输出: 5 2 //输出: ABCDEF
//输出: 7 6
//输出: 7 7 //输出: a
//输出: 14 1
//输出: 14 1
列举选项:
| NSStringEnumerationOptions | 说明 | 
|---|---|
| NSStringEnumerationByLines | 按行 | 
| NSStringEnumerationByParagraphs | 按段落 | 
| NSStringEnumerationByComposedCharacterSequences | 按字符顺序 | 
| NSStringEnumerationByWords | 按单词,字 | 
| NSStringEnumerationBySentences | 按句子 | 
| NSStringEnumerationReverse | 反向遍历 | 
| NSStringEnumerationSubstringNotRequired | 不需要子字符串 | 
| NSStringEnumerationLocalized | 本地化 | 
1.10 字符串编码和转换
//////////字符串编码和转换//////////
NSString *string = @"string"; NSLog(@"最快编码值(枚举): %lu", (unsigned long)string.fastestEncoding);
NSLog(@"最小编码值(枚举): %lu", (unsigned long)string.smallestEncoding);
NSLog(@"UTF8编码值: %s", string.UTF8String);
//输出: 最快编码值(枚举): 1
//输出: 最小编码值(枚举): 1
//输出: UTF8编码值: string
//1.选择编码,是否允许有损编码
- (nullable NSData *)dataUsingEncoding:(NSStringEncoding)encoding allowLossyConversion:(BOOL)lossy;
//2.选择编码
- (nullable NSData *)dataUsingEncoding:(NSStringEncoding)encoding;
//3.判断是否可以无损编码
- (BOOL)canBeConvertedToEncoding:(NSStringEncoding)encoding; //4.C字符编码转换
- (nullable __strong const char *)cStringUsingEncoding:(NSStringEncoding)encoding;
//5.判读C字符转化是否可以成功
- (BOOL)getCString:(char *)buffer maxLength:(NSUInteger)maxBufferCount encoding:(NSStringEncoding)encoding;
//6.指定缓存区转换
- (BOOL)getBytes:(nullable void *)buffer maxLength:(NSUInteger)maxBufferCount usedLength:(nullable NSUInteger *)usedBufferCount encoding:(NSStringEncoding)encoding options:(NSStringEncodingConversionOptions)options range:(NSRange)range remainingRange:(nullable NSRangePointer)leftover; //7.对字符串进行编码时所需的最大字节数
- (NSUInteger)maximumLengthOfBytesUsingEncoding:(NSStringEncoding)enc;
//8.对字符串进行编码时所需的字节数
- (NSUInteger)lengthOfBytesUsingEncoding:(NSStringEncoding)enc; //9.可用字符串编码
+ (const NSStringEncoding *)availableStringEncodings;
//10.本地化编码名称
+ (NSString *)localizedNameOfStringEncoding:(NSStringEncoding)encoding;
//11.默认C字符串编码
+ (NSStringEncoding)defaultCStringEncoding;
1.11 字符串分割
//////////字符串分割//////////
NSString *string = @"A_B_c_D_E_F"; //分割(指定字符串)
NSArray *resultArr1 = [string componentsSeparatedByString:@"_"];
NSLog(@"%@", resultArr1);
//输出: (A, B, c, D, E, F) //分割(指定字符集合)
NSArray *resultArr2 = [string componentsSeparatedByCharactersInSet:[NSCharacterSet lowercaseLetterCharacterSet]];
NSLog(@"%@", resultArr2);
//输出: ("A_B_" , "_D_E_F")
字符集合:
| NSCharacterSet | 说明 | 
|---|---|
| controlCharacterSet | 控制符 | 
| whitespaceCharacterSet | 空格符 | 
| whitespaceAndNewlineCharacterSet | 空格换行符 | 
| decimalDigitCharacterSet | 小数 | 
| letterCharacterSet | 文字 | 
| lowercaseLetterCharacterSet | 小写字母 | 
| uppercaseLetterCharacterSet | 大写字母 | 
| nonBaseCharacterSet | 非基础 | 
| alphanumericCharacterSet | 数字字母 | 
| decomposableCharacterSet | 可分解 | 
| illegalCharacterSet | 非法 | 
| punctuationCharacterSet | 标点 | 
| capitalizedLetterCharacterSet | 大写 | 
| symbolCharacterSet | 符号 | 
| newlineCharacterSet | 换行符 | 
   NSString *string = @"3EWRs a;af";
    //////////修剪//////////
    NSString *result1 = [string stringByTrimmingCharactersInSet:[NSCharacterSet lowercaseLetterCharacterSet]];
    NSLog(@"%@", result1);
    //输出:   3EWRs a;
    //////////填充//////////
    NSString *result2 = [string stringByPaddingToLength: withString:@"填充" startingAtIndex:];
    NSLog(@"%@", result2);
    //输出:   3EWRs a;af充填充填充填充填充填
    //////////折叠//////////
    NSString *result3 = [string stringByFoldingWithOptions:NSNumericSearch locale:[NSLocale systemLocale]];
    NSLog(@"%@", result3);
    //输出:   3EWRs a;af
    //////////替换//////////
    //替换(指定字符串)
    NSString *result4 = [string stringByReplacingOccurrencesOfString:@" " withString:@"替换"];
    NSLog(@"%@", result4);
    //输出:   3EWRs替换a;af
    //替换(指定字符串,条件,范围)
    NSString *result5 = [string stringByReplacingOccurrencesOfString:@"a" withString:@"替换" options:NSRegularExpressionSearch range:NSMakeRange(, string.length - )];
    NSLog(@"%@", result5);
    //输出:   3EWRs 替换;af
    //替换(指定范围)
    NSString *result6 = [string stringByReplacingCharactersInRange:NSMakeRange(, string.length) withString:@"替换"];
    NSLog(@"%@", result6);
    //输出:   替换
1.13 字符串翻译
//////////字符串翻译//////////
NSString *dalian = @"大连";
NSString *result = [dalian stringByApplyingTransform:NSStringTransformMandarinToLatin reverse:NO]; NSLog(@"%@", result);
//输出: dà lián
翻译选项:
| 翻译选择 | 说明 | 
|---|---|
| NSStringTransformLatinToKatakana | 拉丁->片假名 | 
| NSStringTransformLatinToHiragana | 拉丁->平假名 | 
| NSStringTransformLatinToHangul | 拉丁->韩语 | 
| NSStringTransformLatinToArabic | 拉丁->阿拉伯语 | 
| NSStringTransformLatinToHebrew | 拉丁->希伯来语 | 
| NSStringTransformLatinToThai | 拉丁->泰国 | 
| NSStringTransformLatinToCyrillic | 拉丁->西里尔字母 | 
| NSStringTransformLatinToGreek | 拉丁->希腊 | 
| NSStringTransformToLatin | 拉丁 | 
| NSStringTransformMandarinToLatin | 普通话->拉丁 | 
| NSStringTransformHiraganaToKatakana | 平假名->片假名 | 
| NSStringTransformFullwidthToHalfwidth | 全角->半角 | 
| NSStringTransformToXMLHex | XML16进制 | 
| NSStringTransformToUnicodeName | Unicode名 | 
| NSStringTransformStripCombiningMarks | 结合地带商标 | 
| NSStringTransformStripDiacritics | 带音符 | 
1.14 字符串写入
//////////字符串写入//////////
//写入到指定路径,编码的文件中
[string writeToFile:@"/Users/Desktop/LuisX.txt" atomically:YES encoding:NSUTF8StringEncoding error:nil]; //写入到指定URL,编码的文件中
[string writeToURL:[NSURL URLWithString:@"file://LuisX.text"] atomically:YES encoding:NSUTF8StringEncoding error:nil];
二 NSMutableString
NSMutableString是动态的字符串,可以动态的添加,修改,删除等,并且NSMutableString继承自NSString,所以NSString中的方法在NSMutableString都可以使用。
2.1 可变字符串分配容量
提前指定的容量,知识用于内存优化,实际大小可以大于设置的容量capacity
//////////字符串分配容量////////// //1.初始化容量为Capacity大小的字符串 (需要手动释放内存)
NSMutableString *mutableStr1 = [[NSMutableString alloc] initWithCapacity:]; //2.初始化容量为Capacity大小的字符串 (不需要手动释放内存)
NSMutableString *mutableStr2 = [NSMutableString stringWithCapacity:];
2.2 可变字符串扩展方法
   NSMutableString *str = [NSMutableString stringWithString:@"string"];
    //////////插入//////////
    [str insertString:@"" atIndex:];
    NSLog(@"%@", str);
    //输出:   st123ring
    //////////删除//////////
    [str deleteCharactersInRange:NSMakeRange(, )];
    NSLog(@"%@", str);
    //输出:   st3ring
    //////////拼接//////////
    [str appendString:@""];
    NSLog(@"%@", str);
    //输出:   st3ring456
    //////////格式化拼接//////////
    [str appendFormat:@"7 89"];
    NSLog(@"%@", str);
    //输出:   st3ring4567 89
    //////////设置新字符串//////////
    [str setString:@"string"];
    NSLog(@"%@", str);
    //输出:   string
    //////////字符串替换//////////
    //1.指定范围替换
    [str1 replaceCharactersInRange:NSMakeRange(, ) withString:@""];
    NSLog(@"%@", str1);
    //输出:   st123ng
    //2.指定字符串,条件,范围替换
    [str1 replaceOccurrencesOfString:@"" withString:@"--" options:NSRegularExpressionSearch range:NSMakeRange(, str1.length)];
    NSLog(@"%@", str1);
    //输出:   st--ng
OC基础--字符串的更多相关文章
- oc基础  不可变字符串的创建和使用
		oc基础 不可变字符串的创建和使用 简介:下面都是字符串基本用法. 1.字符串的创建 //创建oc常量字符串 NSString *str=@"hello world!"; NSL ... 
- OC基础13:数字、字符串和集合2
		"OC基础"这个分类的文章是我在自学Stephen G.Kochan的<Objective-C程序设计第6版>过程中的笔记. 17.Foundation框架的数组是有序 ... 
- OC基础12:数字、字符串和集合1
		"OC基础"这个分类的文章是我在自学Stephen G.Kochan的<Objective-C程序设计第6版>过程中的笔记. 1.有时要将一些数字数据类型的值当做对象来 ... 
- 【OC基础语法考试】
		OC基础语法已经全部学完,但是这些知识只是最基础的,还有很多高级知识,这个可能需要后面慢慢的去学习才能体会到.接下来我会总结前面的OC基础语法,如果大家发现有什么不正确的地方,请指正,小弟是新生,多请 ... 
- iOS 阶段学习第11天笔记(OC基础知识)
		iOS学习(OC语言)知识点整理 一.OC基础知识 1)#import 用于导入头文件,预处理阶段加载引用,只加载一次. 2)OC 依赖于Foundation框架下的头文件Foundation.h, ... 
- OC基础笔记目录
		OC基础(1) Objective-C简介 OC和C对比 第一个OC程序 面向对象思想 OC基础(2) 类与对象 类的设计 第一个OC类 对象方法的声明和实现 类方法的声明和实现 OC基础(3) 对象 ... 
- OC - 2.OC基础知识介绍
		一.基础语法 1> OC语言和C语言 C语言是面向过程的语言,OC语言是面向对象的语言 OC语言继承了C语言,并增加了面向对象的思想 以下内容只介绍OC语言与C语言的不同之处 2> 关键字 ... 
- OC基础 可变数组与不可变数组的使用
		OC基础 可变数组与不可变数组的使用 1.不可变数组 1.1不可变数组的创建 //实例方法 NSArray *array = [[NSArray alloc] initWithObjects:&quo ... 
- OC基础17:归档
		"OC基础"这个分类的文章是我在自学Stephen G.Kochan的<Objective-C程序设计第6版>过程中的笔记. 1.归档即是用某种格式把一个或多个对象保存 ... 
随机推荐
- Flexible实现H5移动端适配小demo
			前言 看了宇哥关于移动端适配的分享后,加上目前公司项目也需要做移动端适配,今天就抽空搞了搞.目前业界还是比较推崇手淘使用"rem+viewport"的解决方案,今天自己模仿手淘fl ... 
- CSS品控与流程
			精通CSS意味着不仅能写出可用的标记和样式,还能让代码好阅读.方便移植.易维护. 1.外部代码质量:调试CSS 外部代理质量就是用户能体验到的最终结果.主要体现在几个方面. 正确性.CSS属性名都写对 ... 
- 【Mysql】SpringBoot_2.1.0+Druid_1.1.10 配置数据源监控服务Yml格式
			访问地址:localhost:8080/druid 按照这个方法和版本配置没问题 版本或高或低可能会出现不兼容 1.添加依赖 <dependency> <groupId>com ... 
- 栈及其简单应用(python代码)
			栈属于线性结构(Linear Struncture),要搞清楚这个概念,首先要明白”栈“原来的意思,如此才能把握本质."栈“者,存储货物或供旅客住宿的地方,可引申为仓库.中转站,所以引入到计 ... 
- C#LeetCode刷题-树状数组
			树状数组篇 # 题名 刷题 通过率 难度 218 天际线问题 32.7% 困难 307 区域和检索 - 数组可修改 42.3% 中等 315 计算右侧小于当前元素的个数 31.9% 困难 ... 
- Vulnhub篇Photographerr
			0x00 靶机信息 靶机:Photographerr:1 难度:中 下载:https://www.vulnhub.com/entry/photographer-1,519/ 0x01 信息收集 靶场网 ... 
- 通过实际案例摸清楚Spring事务传播的行为
			@ 目录 事务传播 案例准备 案例解析 1.无事务 2. Propagation.REQUIRED 3. Propagation.SUPPORTS 4. Propagation.MANDATORY 5 ... 
- Mybatis中选择语句的使用:<choose>标签、分区排序  Row_num() over ()函数的使用呢
			1.Mybatis中数据库语句的选择 使用: <choose> <when test="relationType=='L'"> ... 
- 在.NET Core中使用MongoDB明细教程(2):使用Filter语句检索文档
			在上篇文章我们介绍了一些驱动程序相关的基础知识,以及如何将文档插入到集合中.在这篇文章中,我们将学习如何从数据库中检索文档. 作者:依乐祝 译文地址:https://www.cnblogs.com/y ... 
- 感谢 Vue.js 拯救我这个前端渣渣,让 PowerJob 有了管理后台界面
			本文适合有 Java 基础知识的人群 作者:HelloGitHub-Salieri HelloGitHub 推出的<讲解开源项目>系列. 对于大部分非前端程序员来说,写网页无疑是一件非常痛 ... 
