======文档更新状态=====
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,10000
2015-12-16 15:27:11.906 1216[1800:1207836] s2:Singleton:MBA,7000
2015-12-16 15:27:11.906 1216[1800:1207836] s1:Singleton:MBA,7000
2015-12-16 15:27:11.907 1216[1800:1207836] s1:0x100100330,s2:0x100100330
2015-12-16 15:27:11.907 1216[1800:1207836] s3:Singleton:New MB,8000,s3:0x100100330
2015-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===============