OC学习_5_关于NSString和单例

来源:互联网 发布:sql创建临时表 编辑:程序博客网 时间:2024/06/05 19:31

======文档更新状态=====
2015-12-16:发布

==================

day05-2015-12-16

一、NSString

1.创建:除了@“…”直接赋值外,还提供很多标准的类方法、对象初始化方法创建并初始化
2.类簇(家族):若干个具有相同特征(属性、方法)的类的组合,在实现细节上可能有所不同,但不太影响使用者的使用方式,只需要知道代表类的用法即可
3.重写description方法:使用NSString的stringWithFormat:…创建自定义格式的字符串后返回;description方法无需手动调用,在使用%@占位符时,会被自动调用
// NSString 的几个函数使用

#import <Foundation/Foundation.h>int main_str(int argc, const char * argv[]) {    NSString* s1=@"hello";NSString* s2=s1;//[NSString stringWithString:s1]; 这个方法与直接用@”hello”能达到相同的结果且没用直接使用@”XXX”方便已不建议               // 使用(当然不建议使用的原因还有其它)    NSLog(@"s1:%@,s2:%@",s1,s2);NSLog(@"s1:%p,s2:%p",s1,s2);// 上面两句执行结果为:// 2015-12-16 14:32:55.063 1216[1721:991585] s1:hello,s2:hello// 2015-12-16 14:32:55.064 1216[1721:991585] s1:0x1000020c0,s2:0x1000020c0//     NSLog(@"s1:%@,s2:%@",[s1 class],[s2 class]);// 此句执行结果为 s1:__NSCFConstantString,s2:__NSCFConstantString                                               // 这里是为了说明NSString 是由类簇组成的,类族了解即可    NSString* s3=[NSString stringWithUTF8String:"hello"];    NSLog(@"s3:%@,%p,%@",s3,s3,[s3 class]);    NSString* s4=[[NSString alloc]initWithUTF8String:"hello"];    NSLog(@"s4:%@,%p,%@",s4,s4,[s4 class]);// 上面几句的执行结果为:// 2015-12-16 14:32:55.065 1216[1721:991585] s3:hello,0x6f6c6c656855,NSTaggedPointerString// 2015-12-16 14:32:55.065 1216[1721:991585] s4:hello,0x6f6c6c656855,NSTaggedPointerString// 这里需要注意当在用一个类时要想到有没有其它方法看到类方法,要想到有没有对象方法(反之亦然)    NSString* s5=[s4 stringByAppendingString:@" world"];    NSLog(@"s5:%@,%p,%@",s5,s5,[s5 class]);    NSString* s6=[s5 stringByAppendingFormat:@":%d,%@.",10,@"iOS"];NSLog(@"s6:%@,%p,%@",s6,s6,[s6 class]);// 上面几句的执行结果为:// 2015-12-16 14:32:55.065 1216[1721:991585] s5:hello world,0x100201b40,__NSCFString// 2015-12-16 14:32:55.065 1216[1721:991585] s6:hello world:10,iOS.,0x100201e60,__NSCFString// 这里演示了stringByAppendingString: 和stringByAppendingFormat:的用法    return 0;}// 关于NSString的简单使用方法:// 1>有些方法已经不建议使用了// 2>NSString 类是由类族组成的// 3>在用到某个类的对象方法时要想到有没有其它方法,有没有类方法(反之亦然)// 4>要注意NSString 有上面的方法(a.创建字符串有快捷方法、类方法b.字符串可以在后面追加字符串然后生成新字符串返回)

// 关于description重写

//  YYPerson.h#import <Foundation/Foundation.h>@interface YYPerson : NSObject{    @private    NSString* _name;    int _age;}+(instancetype)personWithName:(NSString*)name age:(int)age;-(instancetype)initWithName:(NSString*)name age:(int)age;-(void)setAge:(int)age;-(void)setName:(NSString*)name;-(int)age;-(NSString*)name;-(void)say;@end//  YYPerson.m#import "YYPerson.h"@implementation YYPerson+(instancetype)personWithName:(NSString *)name age:(int)age{    return [[self alloc]initWithName:name age:age];}-(instancetype)init{    if (self=[super init]) {        self.name=@"person";        self.age=20;    }    return self;}-(instancetype)initWithName:(NSString *)name age:(int)age{    if (self=[super init]) {        self.name=name;        self.age=age;    }    return self;}-(void)setName:(NSString *)name{    _name=[name copy];}-(void)setAge:(int)age{    if (age<0 || age>150) {        _age=10;    }    else{        _age=age;    }}-(int)age{    return _age;}-(NSString *)name{    return _name;}-(void)say{    NSLog(@"我是%@,今年%d岁。",_name,_age);}/** 1.  对NSObject的description方法的重写, 2.  供占位符%@使用,无需手动调用, 3.  系统自动调用 4.  5.  @return 自定义内容的OC字符串对象 */-(NSString *)description{    return [NSString stringWithFormat:@"我是%@,今年%d岁。",_name,_age];}@end//  test_desc.m#import "YYPerson.h"int main_desc(){    YYPerson* p=[YYPerson personWithName:@"mike" age:20];    NSLog(@"p:%@",p);    NSString* ss=[NSString stringWithFormat:@"this is %@",p];NSLog(@"ss:%@",ss);// 上面几句的结果为:// 2015-12-16 15:02:50.502 1216[1744:1112394] p:我是mike,// 今年20岁。    // 2015-12-16 15:02:50.504 1216[1744:1112394] ss:this is 我// 是mike,今年20岁。// description方法不一定只用在NSLog中,它可以转为字符串插//入到另一个字符串,注意体会上面的过程    YYPerson* p2=[YYPerson personWithName:@"jerry" age:22];    NSLog(@"p:%p,p2:%p",p,p2);NSLog(@"p:%@,p2:%@",p,p2);// 上面几句的结果为://2015-12-1615:02:50.5041216[1744:1112394]    //  p:0x100204da0,p2:0x1001003e0// 2015-12-16 15:02:50.504 1216[1744:1112394] p:我是mike,//  今年20岁。,p2:我是jerry,今年22岁。    return 0;}// 关于description的几点总结1>  NSString 已经重写了description方法2>  其它一般对象的默认description方法格式为:   p:<YYPerson:0x1030026a>3>description不一定只用在NSLog中,它可以转为字符串插入到另一个字符串中,相当于java中的toString方法

. 二、单例Singleton

1.目的:一个类只允许创建一个对象
2.语法规范:+(instancetype)sharedInstance;
3.实现步骤:
A.在一个单例类的实现部分定义一个全局的本类型对象指针(或id类型)_instance
B.在sharedInstance方法中先判断_instance是否为空nil,如果是:则创建对象后返回,如果否:则直接返回
C.在类外创建对象时,不使用alloc而是调用sharedInstance方法
4.改进:重写alloc方法
基本与sharedInstance相同,但为避免递归,调用父类的alloc分配内存:[super alloc]
sharedInstance直接调用alloc方法

关于单例的唐僧解释
单例模式
1.设计模式:23中设计模式之一
2.单例:保证在一个应用程序中某个类只能创建一个对象实例
3.实现(如果直接new或alloc仍然会产生多个对象实例):
A。定义一个单例类的全局变量(在m文件中)
B。定义一个类方法用于创建或者获取单例对象,一般命名为:+(instancetype)sharedInstance;
C。具体实现:先判断全局变量是否为空,如果是则创建后返回,如果不是空则直接返回
4.严格单例,还需重写alloc方法
// 单例的简单写法<暂时不考虑allocWithZone 和copyWithZone已经内存管理>

//  YYSingleton.h#import <Foundation/Foundation.h>/** *  这是一个单例测试类 */@interface YYSingleton : NSObject{    @private    int _price;    NSString* _name;}/** *  这是设置price变量的setter方法 * *  @param price 商品价格 */-(void)setPrice:(int)price;/** 这是设置name变量的setter方法 @param name 商品名称 */-(void)setName:(NSString*)name;-(int)price;-(NSString*)name;+(instancetype)sharedInstance;@end//  YYSingleton.m#import "YYSingleton.h"YYSingleton* _instance; // 定义一个实例全局变量@implementation YYSingleton-(void)setName:(NSString *)name{    _name=[name copy];}-(void)setPrice:(int)price{    _price=price;}-(int)price{    return _price;}-(NSString *)name{    return _name;}-(NSString *)description{    return [NSString stringWithFormat:@"Singleton:%@,%d",_name,_price];}// 定义一个获取单例对象的类方法、注意这里的写法+(instancetype)sharedInstance{    if (_instance==nil)    {        _instance=[[self alloc]init];// 这里的alloc指下面的alloc    }    return _instance;}// 重写alloc方法+(instancetype)alloc{    if (_instance==nil) {        _instance=[super alloc];// 这里不能写成[self alloc]会死循              //环,这里调用的alloc是从父类继承来的alloc    }    return _instance;}@end//  test_singleton.m#import "YYSingleton.h"int main(){    //第一次访问sharedInstance方法,新建对象后返回地址    YYSingleton* s1=[YYSingleton sharedInstance];    [s1 setName:@"MBP"];    [s1 setPrice:10000];    NSLog(@"s1:%@",s1);    //以后再去访问sharedInstance方法,直接返回原对象的地址    YYSingleton* s2=[YYSingleton sharedInstance];    [s2 setName:@"MBA"];    [s2 setPrice:7000];    NSLog(@"s2:%@",s2);    NSLog(@"s1:%@",s1);    NSLog(@"s1:%p,s2:%p",s1,s2);    YYSingleton* s3=[YYSingleton new];    [s3 setName:@"New MB"];    [s3 setPrice:8000];    NSLog(@"s3:%@,s3:%p",s3,s3);    NSLog(@"s1:%@,s1:%p",s1,s1);    return 0;}// 上面几句的结果为:2015-12-16 15:27:11.905 1216[1800:1207836] s1:Singleton:MBP,100002015-12-16 15:27:11.906 1216[1800:1207836] s2:Singleton:MBA,70002015-12-16 15:27:11.906 1216[1800:1207836] s1:Singleton:MBA,70002015-12-16 15:27:11.907 1216[1800:1207836] s1:0x100100330,s2:0x1001003302015-12-16 15:27:11.907 1216[1800:1207836] s3:Singleton:New MB,8000,s3:0x1001003302015-12-16 15:27:11.907 1216[1800:1207836] s1:Singleton:New MB,8000,s1:0x100100330关于单例的一些总结:1>如果上面不重写alloc只是定义一个sharedInstance类方法则用这个方法获取的实例和用alloc init获取的实例不一样所以一定要重写alloc方法2>注意上面重写alloc时用到super的原因3>  上面的单例实现严格上还要考虑allocWithZone,copyWithZone 和一些内存管理4>  再次重复一下实现单例的步骤:A。定义一个单例类的全局变量(在m文件中)B。定义一个类方法用于创建或者获取单例对象,一般命名为:+(instancetype)sharedInstance;C。具体实现:先判断全局变量是否为空,如果是则创建后返回,如果不是空则直接返回4.严格单例,还需重写alloc方法

===============EOF===============

0 0