Objective_C学习笔记
2015-09-01 19:08
323 查看
面向过程
强调的是功能行为
关注的是解决问题需要哪些步骤
面向对象
将功能封装进对象,强调具备功能的对象
关注的是解决问题需要哪些对象
面向对象是基于面向过程的
OC基本所有的关键字以@开头
使用sizeof()判断变量所占用的内存空间:
在64为Mac系统上,short int(2个字节)、int(4)、long int(8)、long long(8)
在iOS系统上,short int(2个字节)、int(4)、long int(4)、long long(8)
Object-c
c
后缀名.m
后缀名 .c
#import #include
可以防止头文件的重复包含
Foundation stdio
NSString ,…
自动释放池
NSLog(@“”); printf(“”);
1自动换行
2添加时间戳(项目名)
3多@
NString * 对象名称=@“字符串内容”;//定义字符串
NSLog(@“ %@ ”,对象名称);
int *p=(int *)malloc(sizeof(int));
对象在栈区分配,记录了在堆区的首地址
注释:
单行注释://
多行注释:/* */
#if 0/1 …………#endif
0被注释 1被启用
NSLog完全具备printf的功能,而printf只能打印纯C语言的变量,不能打印一些NSObject类型的对
象;NSLog(@“ ”)自带换行功能
NSLog函数输出格式
%@ 对象
%d,%i 整数
%u 无符整型
%f 浮点、双字
%X,%x 二进制数
%o 八进制数
%zu size_t
%p 指针
%e 浮点、双字(科学计算(指数))
%g 浮点、双字(
省略小数点后面无意义的零,保留小数点5位有意义的数字)
%s C字符串
%.*s Pascal字符串
%c 字符
%C unichar
%lld 64位长整数(long long)
%llu 无符64位长整数
%Lf 64位双字
%li=%ld
Cocoa对其所有的函数、常量、类型前面都会增加“NS”,前缀用于区分该函数Cocoa,而不是
其他程序包
NSString
NSDate
NSData
UIKit
Foundation
stdio
autoreleasepool自动释放池 //前缀“NS”4.0版本使用
main()函数使用了@autoreleasepool{}来包含所有的代码,位于@autoreleasepool之后的{}被称为自
动释放池,该池会自动回收这些语句所创建的对象。保证Objective-C能自动释放内存,避免引起
内存泄露。
int main() //接口
command+b编译
command+r运行
_____________________________________________________
类是多个同种类型事物的抽象;一个类可以实例化多个对象。
一个类由三部分构成:类的名称、类的属性、类的方法
对象:类类型的变量,是系统中的基本运行实体
方法的声明和实现,都必须以“+”“-”开头
+表示类方法(静态方法),直接用类名即可调用
类方法不能方位实例(成员)变量,类方法由类调用,并没有
创建存储空间来存储类中的成员变量。。格式:[类名 类方法名];
类方法的好处和适用场合:
1、不依赖于对象,执行效率更高
2、能用类方法解决的问题,尽量适用类方法
3、场合:当方法内部不需要使用到成员变量时,可以改为
类方法
-表示对象方法(动态方法),必须用对象才能调用
可以访问当前对象的成员的成员变量。。格式:[对象名 对象方法名];
在.h中声明的所有方法作用域都是public类型,不能更改
成员变量的常用的作用域有3种
1@public全局都可以访问
2@protected只能在类内部和子类中访问
3@private只能在类内部访问
@interface 类名:NSObject
//.h类的声明文件 “:”表示继承
{ //没有属性时,花括号可以省略
NSString * 属性1;
//注意“ * ”
NSInterger 属性2;
}
-(void)方法名;
@end
@implementation
类名 //.m类的实现文件
-(void)方法名
{
NSLog(@“想要输出的内容”);
}
@end
int main()
{
@autoreleasepool
{
类名 * 对象名=[类名 new];
//静态方法new创建一个对象
[对象名 方法名];
}
}
——————————————————————————————————
setter函数,对成员变量赋值
getter函数,对成员变量取值
#pragma mark age 的 setter 和 getter方法
.h
-(void)setAge:(int)newAge
andHeight:(float)newHeight //一个冒号对应一个参数
-(int)age
//get方法
.m
-(void)setAge:(int)newAge
//set合并,get方法不能合并
{
age=newAge;
height=newHeight;
}
-(int)newAge
// get
{
return age;
}
-(float)newHeight
{
return height;
}
int main()
{
[对象名 setAge:数字 setHeight:数字];
NSLog(@“%li%li”,[对象名 参数名],[对象名 参数名]);
}
{}花括号的作用是定义一个代码块
[]方括号的作用是用于访问数组元素
导入文件时,双引号“ ”和尖括号< >的区别
“ ”首先找的是自定义的一些类,之后去系统库中寻找
< >直接去系统库中寻找类的头文件
注意:导入头文件错误(.m)
——————————————————————————————————————
在.m文件里初始化
-(id/instancetype)init{
self=[super init]
if(self){
_name=@“xxx”;
_age=21;
}
return self;
}
//[super init] 的作用:面向对象的体现:先利用父类的init方法为子类实例的父类属性初始化;
self为什么要赋值[super init]:防止父类的初始化release掉self指向的空间并重新alloc一
块空间。[super init]可能失败,这时不执行if
在main函数中
[类名 * 对象名]=[[类名 alloc]init];
NSLog();
或:
.h
-(instancetype)initWithName:(NSString *)name andAge:(NSInteger)age;
get方法;
.m
-(instancetype)initWithName:(NSString*)name andAge:(NSInteger)age{
self=[super init];
if(self){
_name=name;
_age=age;
}
return self;
}
get方法;
main.m
Person *person1=[[Person alloc]init];
[person1 initWithName:@"小A"andAge:10];
NSLog(@"%@%li岁了",[person1 name],[person1 age]);
id 是一个泛型指针,用于各种对象各种指
注意:.m文件缺少get方法
——————————————————————————————————————
合成存取器
自动化@property和@synthesize
.h@property(copy,nonatomic)NSSring*
属性1;
@property(assign,nonatomic)NSInteger
属性2;
.m@synthesize
属性1;
@synthesize
属性2;
car类 属性:品牌 /Color/size/piace 方法:载人 、
#if 0 **** #endif//表示***这段代码被注释,如果if后面是1,表示被启用
——————————————————————————————————————
继承:子类拥有父类所有的属性和方法特征
派生:子类在父类的基础上又增加了新的属性和方法
方法:1,当我们发现我们封装的许多类中,有一部分功能是耦合的,可以使用继承把这些相同的功能模块
封装成一个父类。2,使用继承统一接口【父类指针可以指向子类对象】id指针可以表示任何对象
继承的优点:
1、代码复用
2、代码的扩充:子类在父类的基础上可以增加自己的实例变量和方法
什么时候使用继承:
1、创建大量相似的类
2、继承官方类(alloc init)
Xcode4.5以上的版本可以省略synthesize ’译器会自动帮你加上set get方法实现,并且默认会访问_name定义的属性,如过找不到定义的属性,会自动生成一个_name私有的成员变量,并且默认去访问
——————————————————————————————————————————
封装是面向对象的三大特征之一(继承、多态):将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问
目的:隐藏类的实现细节
让使用者只能通过事先预定的方法来访问数据,从而可以在该方法里加入控制逻辑,限制对成员变量的不合理访问
可进行数据检查,从而有利于保证对象信息的完整性
便于修改,提高代码的可维护性
为了实现良好的封装,需要从以下两个方面考虑:
将对象的成员变量和实现细节隐藏起来,不允许外部直接访问
把方法暴露出来,让方法来控制对这些成员变量进行安全的访问和操作
封装:该隐藏的隐藏,该暴露的暴露,需要通过使用访问控制符来实现
@private @package @protected @public
@public:共有访问
1类中的方法可以直接访问,该类对象可以直接访问
2子类中的方法可以直接访问,子类的对象可以直接访问方法
@protected:保护访问
1类中的方法可以直接访问,该类对象不可以直接访问
2子类中的方法可以直接访问,子类的对象不可以直接访问方法
@private:私有访问
1类中的方法可以直接访问,该类对象不可以直接访问
2子类中的方法不可以直接访问,子类的对象不可以直接访问方法
______________________________________________________________________________
工程名下搜索gar 在错误信息中含有ARC的错误,修改为手动释放
Yes自动释放内存,NO手动释放
只要含有alloc的都要进行release释放
______________________________________________________________________________
实例对象结果调用对象decription方法
-(NSString *)decription
{
return [NSString stringWithFormat:@“age=%d,name=%@”,_age,_name];
}
类对象结果调用类方法decription
{
return @“类方法description”;
}
注意:1、description方法的返回值为NSString类型;2在方法内部使用NSLog(“%@”,self);会引发死循环
————————————————————————————————————————
static关键字不能用于修饰成员变量,它只能修饰局部变量、全局变量和函数,static修饰局部变量表示就爱那个该局部变量存储到静态存储区;static修饰全局变量用于限制该全局变量只能在当前源文件中访问;static修饰函数用于限制该函数只能在当前源文件中调用
——————————————————————————————————————————
复合:一个类由两个或多个其他指针构成,就是一个复合类。
在棧区分配一块内存:动态分配内存
使用复合:复合对象保证对象指针有一个有效的指向;也就是有自持有的内存。
注意:1必须初始化 2setter和getter方法 3property synthesize
在使用中如果定义不同的类型对其使用方式:
@property(copy,nonatomic)NSString
str;字符串
@property(assign,nonatomic)NSInteger
it;整形
@property(retain,nonatomic)Mother *mom;类类型(一般在复合中使用)
return:该属性原来所引用的对象的引用计数减1,被赋值对象的引用计数加1
封装的好处:1.重用;2.不必关心具体的实现;3.面向对象三大特征之一;4具有安全性
———————————————————————————————
(“int”到“课程”的隐式转换是不允许带弧)
比较:上错下对
—————————————————————————————————————
没有返回值导致的
————————————————————————
“==”判断两个变量是否相等时,如果两个变量是基本的变量,且都是数值型
(不一定要求数据类型严格相同),则只要两个变量的值相等,就将返回
真。对于两个指针类型的变量,它们必须指向同一个对象(也就是两个指针 变量保存的内存地址相同)时,==判断才会返回真,如果判断两个没有继承
关系的指针变量时,编译器会提示警告
isEqual:方法是NSObject类提供的一个实例方法,因此,所有的指针变量都可 调用该方法来判断是否与其他指针变量相等。但这个方法判断两个对象相等
的标准与“==”符号没有区别
正确地重写isEqual:方法应该满足下列条件
自反性:对任意x,[x isEqual:x]一定返回真。
对称性:对任意x和y,如果[y isEqual:x]返回真,则[x isEqual:y]也返回值。
传递性:对任意x、y、z,如果有[x isEqual:y]返回真,[x isEqual:y]一定返
回真。
一致型:对任意x和y,如果对象中用于等价比较的关键信息没有改变,那么
无论调用[x isEqual:y]多少次,返回的结果应该保持一致,要么一直是
真,要么一直是假。
对于任何不是nil的x,[x isEqual:,nil]一定返回假
isEqual:首先判断两个对象是否类型一致,在判断具体内容是否一致,如果类型不同直接 return no。
isEqualToString:这个直接判断字符串内容,要确保比较的对象保证是字符串
“==”直接比较指向的地址
————————————————————————
总结:练习的少,过一段时间会忘记某个知识点具体怎么使用,考试的时候没有很好的去分析题意,以至于没写完,程序不细心出的小警告,觉得不重要,就没有截图保存下来
————————————————————————
多态:同一个接口,不同的实现,父类的指针指向不同的子类对象,调用相同的方法,效果不同
多态——--并列类:可以获取自己的属性和方法。对象所在类与开辟空间所对应的类同时声明了一个共同的方法或属性,那么可以对其进行调用。
继承类:只能获取包括本身在内和父类中所有的属性和方法。
使用总结:(正常)多态就是通过父类创建的对象,而对象所指向的子类的不同,而输出不同的结果。如果是并列类,那么那个类创建的对象,就会执行所在类的所有方法和属性,如果在创建空间类中也存在相同的实现,那么就会掉用创建空间的实现内容。
多态在继承中的使用:
1.父类指针可以接收子类的对象(赋值兼容规则)
2.父类的指针指向不同的子类对象,调用相同的方法,效果不同
多态父类不能索取子类中的属性与方法
继承中的子类可以任意获取父类中的属性和方法
并列类可以获取对象自己的属性和方法
对象所在类与开辟空间同时声明一个共同的方法或属性,那么可以对其调用
所创建的对象只能拿自己本身所拥有的属性和方法,无法调用对象开辟空间(那个类)中的所用的属性和方法(只能获取本身类中的方法与属性,其他类中无法获取)
________________________________________________________________’
id数据类型:可以存储任何类型的对象
可声明方法使其具有id类型的返回值
—(id)newObject:(int)type;
SEL类成员方法
在objective——C中,SEL是选择器(selector)的一个类型。选择器就是指向
方法的一个指针。
回调机制
————————————————————————————
什么是Category类别?分类又称为类别、类目、类簇、分支类
分类:在不改变原有类的基础上给这个类增加新的方法
注意:分类只能增加方法,不增加实例变量(分类只扩充方法,不能增加成员变量的定义)
1、Category能把一个类的实现分为若干不同文件中。
2、每个Cagegory是类的一部分。
3、类的不同类别可以单独编译(可以让不同开发者负责一个Category)
4、如果把一个类Category(申明和实现)放到一个.m文件中,那么该Category外界不能访问。这样实现了C++中class的private功能
5、Category实际上就是对类的扩展。
类别的作用:
1.向类中添加方法
2.类别方法的优先级高于类中方法的优先级,类和分类中如果有相同名称的方法(如果相同的话会覆盖掉原来类)
3.将相同作用的方法,放到一个类别中,这样可以降低类中的方法的数量,便于开发和维护
类别3种用法:
1、利用类别对类进行模块化设计
2、使用类别来调用私有方法
3、使用类别来实现非正式协议
类别的使用
1.基本类别无法添加属性
2.在main。m中导入分类的头文件,即可创建主类对象,创建的对象可以调用主类和分类的所有方法(不包括分类的属性)
类别Category命名规范
1、一般Category命名规范
要扩展类名+扩展变量.[hm]
比如:NSString+ReverseString.h
NSString+ReverseString.m
UIImageView+WebCache.h
UIImageView+WebCache.m
2、NSString+Reverse.h头文件
NSString+Reverse.h
#import<Foundation/Foundation.h>
@interface NSString(reverse)
-(NSString *)reverseString
@end
3、unichar c=[self characterAtIndex:--len];
NOLog(@"c is C%",c);
注意这里的c是unichar类型,这里的c是包含2个字节的国际字符,所以用C%来表示。这是OC里面特有的东西。
4、实现函数的私有化
@interface Foo(Private)
- (void) test2;
@end;
@implementation Foo
- (void) test
{
[self test2];
}
- (void) test2
{
NSLog(@"test2 is calling");
}
@end;
这个例子用Category实现了函数的私有化。
创建类别:
1、在分类中先导入主类的头文件
2、在分类的。h和。m文件中把@interface后面修改为:
主类类名(分类类名)
形式:接口 @interface 已有类(类别名)
//方法定义
@end
实现部分@implementation 已有类(类别名)
//方法实现
@end
匿名类别将属性,方法私有化
在OC中,只有类方法和实例方法,不存在私有方法,但是在。m文件中实现而不在。h文件中声明的方法称之为私有方法
扩展相当于匿名类别,语法:
@interface 已有类()
{
实例变量
}
//方法定义
……
@end
私有化后所创建的对象就无法在进行访问,从而进行代码的保护
1--在分类中.m文件中不能使用@synthesize要修改为:@dynamic否则会报错。
2—已经分过类的分类中(不包括主类),不能再次分类
四、字符串的翻转方法函数扩展
建立一个Category的项目后,
NSString+ReverseString.h代码:
#import <Foundation/Foundation.h>
@interface NSString (ReverseString)
- (id) reverseString;
@end
NSString+ReverseString.m
#import "NSString+ReverseString.h"
@implementation NSString (ReverseString)
- (id) reverseString
{
NSUInteger len = [self length];
// self
表示字符串本身
NSMutableString *retStr = [NSMutableString stringWithCapacity:len];
while (len > 0) {
unichar c = [self characterAtIndex:--len];
//
从后取一个字符 unicode
NSLog(@" c is %C", c);
NSString *s = [NSString stringWithFormat:
@"%C", c];
[retStr appendString:s];
}
return retStr;
}
@end
main.m
#import <Foundation/Foundation.h>
#import "NSString+ReverseString.h"
int main (int argc,
const char * argv[])
{
@autoreleasepool {
NSLog(@"Hello, World!");
NSString *string =
@"中国万岁hello";
NSString *retString = [string reverseString];
NSLog(@"ret string is %@", retString);
}
return 0;
}
使用NSString stringWithFormat:类方法创建的字符串对象是运行时创建出来的,它被保存在运行时内存区内(堆内存),不会防区常量池中,因此保存的地址并不相同。
协议的作用类似于接口,用于定义两个或多个类应该遵守的规范。协议不提供任何实现,体现的是规范和实现分离的设计哲学(好处是一种松耦合的设计)
正式协议的定义使用@protocol关键字
@protocol 协议名<父协议1,父协议2>{
零个到多个方法定义……
}
协议名应与类名采用相同的命名规则;
一个协议可以有多个直接父协议,但协议只能继承协议,不能继承类;
协议中定义的方法只有方法签名,没有方法实现;协议中包含的方法既可是
类方法,也可是实例方法;
遵守(实现)协议
语法:@interface 类名:父类<协议1,协议2……>
@implement 类名:父类<协议1,协议2……>
在程序中使用协议来定义变量。语法:
NSObject<协议1,协议2……>*变量;
id<协议1,协议2……>*变量;
正式协议与非正式协议的区别:
1、非正式协议通过为NSObject创建类别来实现,而正式协议则直接使用
@protocol创建
2、遵守非正式协议通过继承带特定类别的NSObject来实现;而遵守正式协议则必须实现协议中定义的所有方法
3、遵守非正式协议不要求实现协议中定义的所方法;而遵守正式协议则必须实现协议中定义的所有方法
@optional:位于该关键字之后、@requird或@end之前声明的方法是可选的
@required:位于该关键字之后、@requird或@end之前声明的方法是必需的
在协议.h文件中缺少@end
协议格式:
1、创建一个.h文件,将Foundation框架复制到该文件中,声明协议
@protocol name<NSObject>
代码(方法)区
@end
2、在对象类中导入协议文件的头文件
3、遵守协议(协议名)
4、.h导入声明的方法
5、.m实现声明的协议方法
1、在对象类中直接添加协议的方法
2、@protocol name<NSObject>
代码(方法)区
@end
3、遵守协议<协议名>
4、.h导入声明的方法
5、.m实现声明的协议方法
委托代理
委托方:
1、先导头文件(协议)
2、delegate
@property(retain,nonatomic)id<saleTo> delegate;
-(void)commond;
3、command方法声明、实现
-(void)commond{
//第1种方法
// [self.delegate performSelector:@selector(方法名)];
//第2种方法
两者任选其一
if([self.delegate respondsToSelector:@selector(方法名)])
{
[self.delegate 方法名 ];
}
}
代理方:
1、先导头文件(协议)
2、协议中的方法实现
main:
1、先导头文件(代理方,委托方)
2、委托方,代理方 都实例化一个对象
3、委托方的对象名.delegate = 代理方对象名
4、【委托方的对象名.delegate 协议中的方法】;
或者【委托方的对象名 command方法】;
双向的委托代理时,必须把协议单独拿出来
这样的警告说只导入协议,没有在。h里面遵守协议
委托代理
错误:终止应用程序由于未捕获的异常,无法识别的选择发送到实例.
原因:如上图,retain,错写成copy
构造函数:为实现某个功能,将属性传入该方法,将属性实现,传参是一种特殊方法。主要用来创建对象时初始化对象,即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中
特点:1.构造函数的命名必须和类名完全相同
2.构造函数的功能主要用于在类的对象创建时定义初始化的状态。它没有返回值,也不能用void来修饰。
3.构造函数不能被直接调用,必须通过new运算符在创建对象时才会自动调用,er一般方法是在程序执行到它的时候才会被调用。
4.当定义一个类的时候,通常情况下都会显示该类的构造函数,并在函数中指定初始化的工作
析构函数:对声明的属性,进行释放
析构函数与构造函数相反,当对象脱离其作用域时(例如对象所在的函数已调用完毕),系统自动执行析构函数。用来“清理善后”工作
使用super关键字调用父类的方法
self是一个指针,只想当前调用此方法的对象,super是一个关键字,不是对象,只是调用父类方法的一种制。
super是指向直接父类的指针,而self是指向本身的指针。self相当于JAVA中的this指针
self:1.调属性(如果调不到,使用下划线属性名)
2.调方法
_____________________________________________________
◆ 字符串
C语言中的字符串:char a[10]=“”;(字符串使用双引号)
单个字符:char a=‘A’;
OC中的字符串:
NSString *str=@“”;
区别:1、“类型修饰符” 2、@“”
最常用的方法:NSString *string = @“字符串”;(只能用来初始化不可变字符串,不能用来初始化可变字符串)
不兼容的类型的指针初始化一个NSMutableString *表达型”NSString *”
1:对象方法
- (instancetype)initWithFormat:(NSString *)format, …;//通过格式化控制初始化字符串
- (instancetype)initWithUTF8String:(const char *)bytes;//通过c字符串初始化oc字符串
2:类方法
+ (instancetype)stringWithString:(NSString *)aString;
+ (instancetype)stringWithFormat:(NSString *)format,, …;
+ (instancetype)stringWithUTF8String:(const char *)bytes;
- (NSString *)stringByAppendingString:(NSString *)aString;
错误
UTF赋值时不能加@
2:求字符串的长度
- (NSUInteger)length;//返回字符串的长度(自带的一个属性)
3:通过索引获取字符串中相应字符(字符串中成员的引用)
-
(unichar)characterAtIndex:(NSUInteger)index;//返回获取的字符
4:字符串的比较
//判断两个字符串是否相等
- (BOOL)isEqualToString:(NSString *)aString;
//比较两个字符串大小
- (NSComparisonResult)compare:(NSString *)aString;
//比较字符串时不区分大小写比较大小(输入验证码)
- (NSComparisonResult)caseInsensitiveCompare:(NSString *)aString;
5:字符串中查找子串(strstr)
- (NSRange)rangeOfString:(NSString *)aString;//在self中找aString
6:判断前后缀
- (BOOL)hasPrefix:(NSString *)aString;//前缀
- (BOOL)hasSuffix:(NSString *)aString;//后缀
7:字符串转数字
- (double)doubleValue;
- (float)floatValue;
- (int)intValue;
- (NSInteger)integerValue ;
- (long long)longLongValue ;
- (BOOL)boolValue ;
8:小写和大写之间转换
- (NSString *)uppercaseString;//小写转大写
- (NSString *)lowercaseString;//大写转小写
- (NSString *)capitalizedString;//首字母大写
9:字符串提取
- (NSString *)substringFromIndex:(NSUInteger)from;//从from位置开始一直提取到字符串的末尾
- (NSString *)substringToIndex:(NSUInteger)to;//从字符串开始提取到to位置结束
- (NSString *)substringWithRange:(NSRange)range;//提取字符串中的某个返回
与NSMutableString字符串相关操作
NSMutableString 可变字符串,字符串中的内容可以进行修改,继承于NSString
字符串追加:1、字符串;2、格式符
1:在字符串的末尾追加子符串
- (void)appendString:(NSString *)aString;
2:在字符串末尾追加格式化子符串
- (void)appendFormat:(NSString *)format, ... ;//追加的字符串是格式化字符串
3:指定索引位置插入子符串
- (void)insertString:(NSString *)aString atIndex:(NSUInteger)loc;//将在self中插入aString字符串,后面的字符串内容后移,改变了self字符串中内容
4:删除指定范围的子符串
- (void)deleteCharactersInRange:(NSRange)range;
5:修改子符串
- (void)setString:(NSString *)aString;//把整个字符串变成aString
可变字符串如果直接初始化,不能使用append追加
区别下面两种初始化上面的不可以追加,下面的可以追加
NSString *str=@"abcdefg.com";
NSMutableString *mstr1=@"###";
NSMutableString *mstr=[[NSMutableString alloc]initWithString:@"das"];
NSLog(@"1%@",mstr);
//可变字符串的拼接(尾部追加)
[mstr appendString:@"123"];
NSLog(@"2%@",mstr);
[mstr appendFormat:@"aa"];
NSLog(@"3%@",mstr);
[mstr appendString:str];
NSLog(@"4%@",mstr);
//插入字符串
[mstr insertString:mstr1 atIndex:2];
NSLog(@"5%@",mstr);
//删除
NSRange ra;
ra.length=5;
ra.location=2;
[mstr deleteCharactersInRange:ra];
NSLog(@"6%@",mstr);
//修改
[mstr setString:@"****"];
NSLog(@"7%@",mstr);
___________________________________
数组
C:
char 数组名[长度]={‘a’,’b’,’c’……};
OC:
NSArray *array
for (类型 *名字 in
所遍历的对象){
code……
})
2:c中数组和oc中数组的区别
c中的数组,数组成员一般都是基本数据类型变量,数组成员的数据类型要相同,数组没有结束的标志,数组成员的值可以直接修改
oc中的数组,数组成员一般是oc对象(也可以间接存储基本数据类型(int,float)或复合类型的数据),数组成员的数据类型可以不相同,数组末尾有结束标志nil(因为数组成员是对象指针),NSArray数组成员不能修改,NSMutableArra y数组成员可以修改
3:NSArray:不可变数组
不可变:数组一旦创建完成后,数组成员不能够被修改,数组成员不能添加和删除
注:oc中的数组成员放在小括号里(),nil是数组结束标志
1:数组的创建
常用方法:NSArray *array = @[成员列表];//只能用在不可变数组中(无需写nil)
1:对象方法//讲课时强调成员类型id,验证数组成员类型任意并且可以各不相同//将nil放到数组中间,再打印数组内容看下结果//打印的时候()里面的内容就是数组//数组成员全是中文是打印出来就是所谓的乱码,其实是网络格式
- (id)initWithObjects:(id)firstObj,
... ;(记住)
NSArray *array=[[NSArray
alloc]initWithObjects:@"ab",@"bc",@"cd",
nil];
- (id)initWithArray:(NSArray
*)array;//由于内存管理技术,导致initWithArray的数组,与原数组的地址不同
2:类方法
+ (id)arrayWithObjects:(id)firstObj,
... ;
+ (id)arrayWithArray:(NSArray *)array;
//数组的创建
void createArray(void){
//注意:数组成员初始化的时候放在[]里,打印出来的时候放在()
NSArray *array =
@[@"bei",
@"jing", @"huan",
@"huan", @"ying",
@"nin"];
#pragma mark 对象方法创建数组
//注意:nil是oc数组结束标志,如果nil在数组中间,nil后面的元素无法打印
NSArray *array1 = [[NSArray
alloc]
initWithObjects:@"bei",
@"jing", @"huan",
@"huan", @"ying",
@"nin", nil];//最常用
NSArray *array2 = [[NSArray
alloc] initWithArray:array];//用其他数组初始化当前数组
#pragma mark 类方法创建数组
NSArray *array3 = [NSArray
arrayWithObjects:@"bei",
@"jing", @"huan",
@"huan", @"ying",
@"nin", nil];//最常用
NSArray *array4 = [NSArray
arrayWithArray:array];
NSLog(@"%@", array);
NSLog(@"%@", array1);
NSLog(@"%@", array2);
NSLog(@"%@", array3);
NSLog(@"%@", array4);
}
练习1:
1:分别用对象方法和类方法分别创建一个数组array1,array2,数组成员有三个字符串@“a”,@“b”,@“c”,然后再创建一个数组array,数组成员是array1, array2
//1:分别用对象方法和类方法分别创建一个数组array1,array2,数组成员有三个字符串@“a”,@“b”,@“c”,然后再创建一个数组array,数组成员是array1,
array2
void test1(void){
//对象方法
NSArray *array1 = [[NSArray
alloc] initWithObjects:@"a",
@"b",
@"c", nil];
//类方法
NSArray *array2 = [NSArray
arrayWithObjects:@"a",
@"b",
@"c", nil];
NSArray *array = [NSArray
arrayWithObjects:array1, array2,
nil];
NSLog(@"%@", array);
}
练习2:
2:请用类方法做一个数组,数组长度为2,数组中第一个元素是一个数组,第二个元素也是一个数组,第一个元素的数组长度为2,每个成员又是一个数组,两个小数组分别为2,3,存的都是字符串,内容为A、B 和A、B、C, 第二个元素的数组长度为1,存的一个字符串A
//2:请用类方法做一个数组,数组长度为2,数组中第一个元素是一个数组,第二个元素也是一个数组,第一个元素的数组长度为2,每个成员又是一个数组,两个小数组分别为2,3,存的都是字符串,内容为A、B
和A、B、C,
第二个元素的数组长度为1,存的一个字符串A
void test2(void){
NSArray *array1_1 = [NSArray
arrayWithObjects:@"A",
@"B",
nil];
NSArray *array1_2 = [NSArray
arrayWithObjects:@"A",
@"B",
@"C", nil];
NSArray *array1 = [NSArray
arrayWithObjects:array1_1, array1_2,
nil];
NSArray *array2 = [NSArray
arrayWithObjects:@"A",
nil];
NSArray *array = [NSArray
arrayWithObjects:array1, array2,
nil];
NSLog(@"%@", array);
}
2:获取数组元素的个数
- (NSUInteger)count;//返回数组中元素个数
3:通过索引获取相应的元素//返回什么类型元素就要用什么类型对象接收//下标越界会报错
- (id)objectAtIndex:(NSUInteger)index;
//数组元素个数
void countOfArray(void){
NSArray *array = [NSArray
arrayWithObjects:@"bei",
@"jing", @"huan",
@"ying", @"nin",
nil];
NSLog(@"%lu", [array
count]);
}
//数组成员的引用
void objectInArray(void){
NSArray *array = [NSArray
arrayWithObjects:@"bei",
@"jing", @"huan",
@"ying", @"nin",
nil];
NSLog(@"%@", [array
objectAtIndex:1]);
NSLog(@"%@", array[1]);
}
1:分别用对象方法和类方法分别创建一个数组array1,array2,数组成员分别是三个字符串@“a”,@“b”,@“c”和@“e”. @“f”, @“g”,然后再创建一个数组array,数组成员是array1, array2,取出array的第一个成员,输出该成员下表为1的成员值。
//1:分别用对象方法和类方法分别创建一个数组array1,array2,数组成员分别是三个字符串@“a”,@“b”,@“c”和@“e”. @“f”, @“g”,然后再创建一个数组array,数组成员是array1,
array2,取出array的第一个成员,输出该成员下表为1的成员值。
void test3(void){
NSArray *array1 = [NSArray
arrayWithObjects:@"a",@"b",@"c",
nil];
NSArray *array2 = [NSArray
arrayWithObjects:@"e",@"f",@"g",
nil];
NSArray *array = [NSArray
arrayWithObjects:array1, array2,
nil];
NSLog(@"%@", [[array
objectAtIndex:0]
objectAtIndex:1]);
}
练习3:
循环遍历数组中每个成员的值,并输出
void test4(void){
NSArray *array = [NSArray
arrayWithObjects:@"bei",
@"jing", @"huan",
@"ying", @"nin",
nil];
#if 0
NSUInteger count = [array count];
for (int i=0; i<count; i++) {
NSLog(@"%@", [array objectAtIndex:i]);
NSLog(@"%@", array[i]);
}
#endif
#if 0
for (NSString *string
in array) {
NSLog(@"%@", string);
}
#endif
for (id temp
in array) {
NSLog(@"%@", temp);
}
}
4:数组成员的遍历(traverse)
1:for
2:快速枚举法for-in
//第一种数组成员的类型全部相同且已知(例如:类型全为NSString)
//第二种数组成员的类型不相同,且类型不已知(用id)
练习4:创建一个数组,长度为4,每个都是字符串,依次为abc, EFG, JQK, LIU
//分别使用循环变量和快速遍历方式遍历这个数组,打印数组中的每一个元素
5:通过对象地址获取在数组中的索引值
- (NSUInteger)indexOfObject:(id)anObject;
//通过成员值找对应下标
void indexOfArray(void){
NSArray *array = [NSArray
arrayWithObjects:@"bei",
@"jing", @"huan",
@"ying", @"nin",
nil];
NSLog(@"%lu", [array
indexOfObject:@"bei"]);
}
6:判断数组中是否包含某个元素
- (BOOL)containsObject:(id)anObject;
//判断数组中是否包含某个元素
void isContainObject(void){
NSArray *array = [NSArray
arrayWithObjects:@"bei",
@"jing", @"huan",
@"ying", @"nin",
nil];
BOOL bl = [array
containsObject:@"huan"];
if (bl) {
NSLog(@"包含该元素");
} else {
NSLog(@"不包含该元素");
}
}
7:获取数组的最后一个元素
- (id)lastObject;
//获取数组中最后一个元素
void lastObject(void){
NSArray *array = [NSArray
arrayWithObjects:@"bei",
@"jing", @"huan",
@"ying", @"nin",
nil];
NSLog(@"%@", [array
lastObject]);
NSLog(@"%@", [array
objectAtIndex:[array
count]-1]);
}
例子:将字符串chen$chao$ni$hao$ma变成chen chao ni hao ma
8:数组成员用指定字符串进行分割//将字符串拆成数组对象(字符串的方法,将字符串进行切割成数组,分割成的每个部分是数组成员)
- (NSArray *)componentsSeparatedByString:(NSString
*)separator;
9:把数组元素内容按照字符串separator进行拼接//将数组成员拼成字符串
- (NSString *)componentsJoinedByString:(NSString
*)separator;
//将字符串chen$chao$ni$hao$ma变成字符串chen chao ni hao ma
void separteAndJoin(void){
NSString *string =
@"chen$chao$ni$hao$ma";
//- (NSArray *)componentsSeparatedByString:(NSString *)separator;
//作用:字符串的切割,将字符串切成数组(字符串方法)
NSArray *arrayFromString = [string
componentsSeparatedByString:@“$”];//只能去除一个特殊符号
NSLog(@"%@", arrayFromString);
//- (NSString *)componentsJoinedByString:(NSString *)separator;
//作用:将数组元素拼成字符串(数组方法)
NSString *stringFromArray = [arrayFromString
componentsJoinedByString:@" "];
NSLog(@"%@", stringFromArray);
}
练习5:将字符串中的国军改成XXXX
字符串:@“今天是国庆节,我观看了中国军队演习,中国军队威武,中国军队霸气,中国军队万岁,中国军队雄起”
//练习5:将字符串中的国军改成XXXX
//字符串:@“今天是国庆节,我观看了中国军队演习,中国军队威武,中国军队霸气,中国军队万岁,中国军队雄起”
void test6(void){
NSString *string =
@"今天是国庆节,我观看了中国军队演习,中国军队威武,中国军队霸气,中国军队万岁,中国军队雄起";
// NSArray *arrayFromString = [string componentsSeparatedByString:@"国军"];
// NSString *stringFromArray = [arrayFromString componentsJoinedByString:@"XXXX"];
NSLog(@"%@", [[string
componentsSeparatedByString:@"国军"]
componentsJoinedByString:@"XXXX"]);
}
例子:将chen$chao#ni@hao&ma变成chen
chao ni hao ma
10:按照字符集合分割
- (NSArray *)componentsSeparatedByCharactersInSet:(NSCharacterSet
*)separator
//例子:将chen$chao#ni@hao&ma变成chen chao ni hao ma
void charaterAndJoin(void){
NSString *string =
@"chen$chao#ni@hao&ma";
//- (NSArray *)componentsSeparatedByCharactersInSet:(NSCharacterSet *)separator NS_AVAILABLE(10_5, 2_0);
//作用:按照字符集进行切割
NSArray *arrayFromString = [string
componentsSeparatedByCharactersInSet:[NSCharacterSet
characterSetWithCharactersInString:@"$#@&"]];
NSLog(@"%@", arrayFromString);
NSString *stringFromArray = [arrayFromString
componentsJoinedByString:@" "];
NSLog(@"%@", stringFromArray);
}
练习6:将字符串@“bei$jing%huan*ying nin”字符串变成
bei -jing-huan-ying-nin
//练习6:将字符串@“bei$jing%huan*ying nin”字符串变成
//bei-jing-huan-ying-nin
void test7(void){
NSString *string =
@"bei$jing%huan*ying nin";
NSLog(@"%@", [[string
componentsSeparatedByCharactersInSet:[NSCharacterSet
characterSetWithCharactersInString:@"$%* "]]componentsJoinedByString:@"-"]);
}
4:NSMutableArray:可变数组,继承自NSArray
可变数组:数组创建后,数组成员仍然可以修改,添加和删除
1:初始化可变数组
NSMutableArray *mutable = [[NSMutableArray
alloc] initWithCapacity:0];
NSMutableArray *mutable1 = [NSMutableArray
arrayWithCapacity:0];
1:增加元素
1:在数组末尾追加(插入)元素
- (void)addObject:(id)anObject;
2:在数组末尾追加(插入)一个数组
- (void)addObjectsFromArray:(NSArray
*)otherArray;
3:指定索引位置处插入元素
- (void)insertObject:(id)anObject
atIndex:(NSUInteger)index;
//在可变数组中增加元素
void addObjectInMutableArray(void){
NSArray *array = [NSArray
arrayWithObjects:@"huan",
@"ying",
@"nin", nil];
NSMutableArray *mutableArray = [NSMutableArray
arrayWithCapacity:0];//创建空数组
//- (void)addObject:(id)anObject;
//作用:在数组末尾添加元素
[mutableArray addObject:@"bei"];
[mutableArray addObject:@"jing"];
[mutableArray addObject:@"huan"];
[mutableArray addObject:@"ying"];
[mutableArray addObject:@"nin"];
NSLog(@"%@", mutableArray);
//- (void)addObjectsFromArray:(NSArray *)otherArray;
//作用:数组末尾添加一个数组
[mutableArray addObjectsFromArray:array];
NSLog(@"%@", mutableArray);
[mutableArray insertObject:@"hen"
atIndex:2];
[mutableArray insertObject:@"hen"
atIndex:6];
NSLog(@"%@", mutableArray);
}
2:删除元素
1:删除最后一个元素
- (void)removeLastObject;
2:删除指定索引的元素
- (void)removeObjectAtIndex:(NSUInteger)index;
3:删除指定元素//有多少删除多少
- (void)removeObject:(id)anObject;
4:在一定范围内删除指定元素
- (void)removeObject:(id)anObject
inRange:(NSRange)range;
5:格局一个数组删除指定的元素
- (void)removeObjectsInArray:(NSArray
*)otherArray;
6:删除所有元素
- (void)removeAllObjects;
//在数组中删除元素
void removeObject(void){
NSMutableArray *mutableArray = [NSMutableArray
arrayWithCapacity:0];
[mutableArray addObject:@"bei"];
[mutableArray addObject:@"jing"];
[mutableArray addObject:@"huan"];
[mutableArray addObject:@"ying"];
[mutableArray addObject:@"nin"];
[mutableArray addObject:@"jing"];
#if 0
//- (void)removeObject:(id)anObject;
//作用:删除指定元素
[mutableArray removeObject:@"jing"];
#endif
#if 0
//- (void)removeObjectAtIndex:(NSUInteger)index;
//作用:删除指定下标的元素
[mutableArray removeObjectAtIndex:1];
#endif
#if 0
//- (void)removeObjectsInRange:(NSRange)range;
//作用:
删除指定范围内的元素
NSRange range = {0,
2};//大括号
[mutableArray removeObjectsInRange:range];
#endif
#if 0
NSRange range = {0,
2};
//- (void)removeObject:(id)anObject inRange:(NSRange)range;
//作用:删除指定范围内的某个元素
[mutableArray removeObject:@"jing" inRange:range];
#endif
[mutableArray removeAllObjects];
NSLog(@"%@", mutableArray);
}
3:替换指定索引的元素
- (void)replaceObjectAtIndex:(NSUInteger)index
withObject:(id)anObject;
//数组元素的替换
void replaceObject(void){
NSMutableArray *mutableArray = [NSMutableArray
arrayWithCapacity:0];
[mutableArray addObject:@"bei"];
[mutableArray addObject:@"jing"];
[mutableArray addObject:@"huan"];
[mutableArray addObject:@"ying"];
[mutableArray addObject:@"nin"];
[mutableArray replaceObjectAtIndex:0
withObject:@"nan"];
NSLog(@"%@", mutableArray);
}
4:交换数组元素
- (void)exchangeObjectAtIndex:(NSUInteger)idx1
withObjectAtIndex:(NSUInteger)idx2;
//数组成员的交换
void exchangeObject(void){
NSMutableArray *mutableArray = [NSMutableArray
arrayWithCapacity:0];
[mutableArray addObject:@"bei"];
[mutableArray addObject:@"jing"];
[mutableArray addObject:@"huan"];
[mutableArray addObject:@"ying"];
[mutableArray addObject:@"nin"];
[mutableArray exchangeObjectAtIndex:0
withObjectAtIndex:2];
NSLog(@"%@", mutableArray);
}
练习:创建一个数组,数组成员是5个字符串@“bei”,@“jing”,@“huan”,@“huan”,@“ying”,@“nin”,用冒泡法对数组成员进行排序
5:排序:根据排序准则排序
- (void)sortUsingSelector:(SEL)comparator;
//创建一个数组,数组成员是5个字符串@“bei”,@“jing”,@“huan”,@“huan”,@“ying”,@“nin”,用冒泡法对数组成员进行排序
void test9(void){
#if 0
NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:0];
[mutableArray addObject:@"bei"];
[mutableArray addObject:@"jing"];
[mutableArray addObject:@"huan"];
[mutableArray addObject:@"ying"];
[mutableArray addObject:@"nin"];
NSUInteger count = [mutableArray count];
for (int j=0;j<count; j++) {//冒泡执行的次数
for (int i=0; i<count-1; i++) {//冒泡
if ([[mutableArray objectAtIndex:i] compare:[mutableArray objectAtIndex:i+1]] == NSOrderedDescending) {//相邻成员比较
[mutableArray exchangeObjectAtIndex:i withObjectAtIndex:i+1];//交换
}
}
}
NSLog(@"%@", mutableArray);
#endif
NSArray *array = [NSArray
arrayWithObjects:@"bei",
@"jing", @"huan",
@"ying", @"nin",
nil];
//注意:SEL----->@selector(方法名)
NSArray *arraySort = [array
sortedArrayUsingSelector:@selector(compare:)];
NSLog(@"%@", arraySort);
}
6:修改数组
- (void)setArray:(NSArray *)otherArray;
__________________________________
删除字符串里的符号
或
删除数字
__________________________________________________________________________
字典
key—拼音、部首
value—值(汉字)
oc中的字典:类型NSDictionary,具有键(key)和值(value),键就相当于索引,键值是唯一的,值就相当于内容,一般情况下我们可以通过键(key)找到值(value)
字典的使用:字典类型主要用于plist文件
2:字典的元素
字典的元素是键值对,所以字典的元素都是成对出现的,一个元素就是一对(有key和对应的value)
键和值都是对象类型,键和值的类型可以不同
键值对:(必须成对出现,key不可以重复)
在oc字典中,不能出现相同的key,但是可以出现相同的value,保证key的唯一性,这样就能够通过key唯一确定一个value
4:如何查找值
一般情况下,通过key找value,特殊情况下直接找value
5:NSDictionary:不可变字典
不可变字典:字典对象一旦创建完成后,字典成员不能够被修改,增加和删除
1:字典的创建//输出字典成员的时候发现字典中成员是无序的并且字典输出时内容放在{}中
//key在前value在后注意key与value中间冒号“:”隔开,结束不用nil
NSDictionary *dictionary =
@{@"key1":
@"value1",
@"key2":
@"value2"};
1:对象方法//value在前key在后
- (id)initWithObjectsAndKeys:(id)firstObject,
…;(记住)
- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray
*)keys;
2:类方法
+ (id)dictionaryWithObjectsAndKeys:(id)firstObject,
...;
+ (id)dictionaryWithObjects:(NSArray
*)objects forKeys:(NSArray *)keys;
//不可变字典的创建
void createDictionary(void){
// NSString *string = @"chen chao";
// NSArray *array = @[@"bei", @"jing"];
//字典中的元素放在大括号里的
NSDictionary *dictionary =
@{@"key1":@"value1",
@"key2":@"value2"};//比较常用
#pragma mark 对象方法创建字典
NSDictionary *dictionary1 = [[NSDictionary
alloc] initWithObjectsAndKeys:@"value1",
@"key1",
@"value2",
@"key2", nil];//最常用
NSDictionary *dictionary2 = [[NSDictionary
alloc] initWithDictionary:dictionary];//用其他字典来初始化当前字典对象
#pragma mark 类方法创建字典
NSDictionary *dictionary3 = [NSDictionary
dictionaryWithObjectsAndKeys:@"value1",
@"key1",
@"value2",
@"key2", nil];
NSDictionary *dictionary4 = [NSDictionary
dictionaryWithDictionary:dictionary];
NSLog(@"%@", dictionary);
NSLog(@"%@", dictionary1);
NSLog(@"%@", dictionary2);
NSLog(@"%@", dictionary3);
NSLog(@"%@", dictionary4);
}
2:获取键值对的个数
- (NSUInteger)count;
3:根据键key获取相应值value
- (id)objectForKey:(id)aKey;
4:获取字典中所有的key
- (NSArray *)allKeys;
练习1:输出字典中所有的value值
//练习1:输出字典中所有的value值
void test1(void){
NSDictionary *dictionary = [NSDictionary
dictionaryWithObjectsAndKeys:@"value1",
@"key1",
@"value2",
@"key2", nil];
NSArray *arrayKey = [dictionary
allKeys];//获取字典中所有的key值
for (NSString *key
in arrayKey) {//取出每个key
NSLog(@"%@", [dictionary
objectForKey:key]);//根据key找到对应的value
}
}
5:获取与某个值value对应的所有键key
- (NSArray *)allKeysForObject:(id)anObject;
6:获取字典中的所有值
- (NSArray *)allValues;
//根据value找key
void fromValueToFindKey(void){
NSDictionary *dictionary = [NSDictionary
dictionaryWithObjectsAndKeys:@"value1",
@"key1",
@"value1",
@"key2", nil];
//- (NSArray *)allKeysForObject:(id)anObject;
//作用:根据value找到所有的key
NSArray *array = [dictionary
allKeysForObject:@"value1"];
NSLog(@"%@", array);
}
//获取数组中所有的value
void allValue(void){
NSDictionary *dictionary = [NSDictionary
dictionaryWithObjectsAndKeys:@"value1",
@"key1",
@"value2",
@"key2", nil];
NSLog(@"%@", [dictionary
allValues]);
}
练习2:创建一个字典,字典中有四个键值(key-value)对,分别是title=nike, price=10,info=good shoes, pic=shoes picture,输出键值对的个数,输出字典中所有的key和value,通过title找出对应的value值并输出
//练习2:创建一个字典,字典中有四个键值(key-value)对,分别是title=nike, price=10, info=good shoes, pic=shoes picture,输出键值对的个数,输出字典中所有的key和value,通过title找出对应的value值并输出
void test2(void){
NSDictionary *dictionary = [NSDictionary
dictionaryWithObjectsAndKeys:@"nike",
@"title", @"10",
@"price", @"good shoes",
@"info", @"shoes picture",
@"pic", nil];
NSLog(@"%lu", [dictionary
count]);
NSLog(@"%@", [dictionary
allKeys]);
NSLog(@"%@", [dictionary
allValues]);
NSLog(@"%@", [dictionary
objectForKey:@"title"]);
}
6:NSMutableDictionary:可变字典
可变字典:字典对象一旦创建完成后,字典成员仍然能够被修改,增加和删除
可变字典初始化
NSMutableDictionary *mutableDictionary1 = [[NSMutableDictionary
alloc]
initWithCapacity:0];
NSMutableDictionary *mutableDictionary2 = [NSMutableDictionary
dictionaryWithCapacity:0];
1:增加
1:在字典末尾增加一个键值对
- (void)setObject:(id)anObject
forKey:(id <NSCopying>)aKey;
2:在字典末尾增加一个字典
- (void)addEntriesFromDictionary:(NSDictionary
*)otherDictionary;
//给字典添加元素
void addObjectAndKey(void){
NSDictionary *dictionary = [NSDictionary
dictionaryWithObjectsAndKeys:@"value3",@"key3",
nil];
NSMutableDictionary *mutableDictionary = [NSMutableDictionary
dictionaryWithCapacity:0];
//string: stringByAppendingString
//mutableString: appendString
//mutableArray:addObject
//- (void)setObject:(id)anObject forKey:(id <NSCopying>)aKey;
//作用:在字典末尾增加元素
[mutableDictionary setObject:@"value1"
forKey:@"key1"];
[mutableDictionary setObject:@"value2"
forKey:@"key2"];
NSLog(@"%@", mutableDictionary);
//- (void)addEntriesFromDictionary:(NSDictionary *)otherDictionary;
//作用:在可变字典末尾添加一个字典
[mutableDictionary addEntriesFromDictionary:dictionary];
NSLog(@"%@", mutableDictionary);
}
2:删除
1:根据键key删除键值对
- (void)removeObjectForKey:(id)aKey;
2:删除所有键值对
- (void)removeAllObjects;
//删除字典中的元素
void removeObjectAndKey(void){
NSMutableDictionary *mutableDictionary = [NSMutableDictionary
dictionaryWithCapacity:0];
[mutableDictionary setObject:@"value1"
forKey:@"key1"];
[mutableDictionary setObject:@"value2"
forKey:@"key2"];
[mutableDictionary setObject:@"value3"
forKey:@"key3"];
//- (void)removeObjectForKey:(id)aKey;
//作用:删除字典中的某个键值对
[mutableDictionary removeObjectForKey:@"key1"];
NSLog(@"%@", mutableDictionary);
//- (void)removeAllObjects;
//作用:删除字典中所有的键值对
[mutableDictionary removeAllObjects];
NSLog(@"%@", mutableDictionary);
}
4:修改整个字典
//修改整个字典
- (void)setDictionary:(NSDictionary *)otherDictionary;
//修改键值对
//key不存在表示增加 key存在表示修改key对应的值
- (void)setObject:(id)anObject forKey:(id
<NSCopying>)aKey;
//修改字典
void setMutableDictionary(void){
NSMutableDictionary *mutableDictionary = [NSMutableDictionary
dictionaryWithCapacity:0];
[mutableDictionary setObject:@"value1"
forKey:@"key1"];
[mutableDictionary setObject:@"value2"
forKey:@"key2"];
[mutableDictionary setObject:@"value3"
forKey:@"key3"];
NSLog(@"%@", mutableDictionary);
[mutableDictionary setObject:@"value4"
forKey:@"key1"];
NSLog(@"%@", mutableDictionary);
NSDictionary *dictionary = [NSDictionary
dictionaryWithObjectsAndKeys:@"value4",
@"key4",
nil];
[mutableDictionary setDictionary:dictionary];
NSLog(@"%@", mutableDictionary);
}
_____________________________________________________
单例
共享资源,优化内存
——————————————————————————————————————————————
析构函数
-(void)dealloc
{
[_name release];
或_name=nil;
[super dealloc];
}
@end
——————————————————————————————————————————
#pragma mark - ** 快速找到文件
电脑休眠 格式:
【NSThread sleepForTimeInterval:1】;//暂停1秒
________________________________________________________
数据存储
1:为什么要使用数据持久化
思考:我们使用的qq登录信息,播放器里播放记录,浏览器的收藏,为什么是在每次启动应用程序的时候,这些信息都会存在?正常情况下应用程序结束时,程序中所使用的数据都会被系统自动释放,如果想把程序运行过程中或程序运行结束后的某些信息持久化的保存起来,这时候就用到的数据持久化
2:什么是数据持久化
数据持久化:将数据模型转换成存储模型(将内存中的数据保存到磁盘中)
3:数据持久化的优点
将数据持久的保存起来,不会丢失
4:数据持久化的方式
1:文件
2:Plist文件: 也称之为属性化列表文件,plist文件是一个轻量级的数据库,用于存放一些比较小的数据,文件是xml格式的,只能保存NSArray和NSDictionary
3:归档和反归档:归档是将内存中的任意类型对象写入文件保存到磁盘中,反归档是将磁盘中的文件还原成原来的变量
4:NSUserDefault:持久化标签(UI)
5:数据库:网络 FMDB:世纪封装sqlite数据库 coredata:在数据库的基础上增加了面向对象的语法 第三方的库
PList
1:什么是plist文件
plist全称:property List 属性列表文件,plist是一个xml格式文件,后缀为.plist,只能持久化NSArray和NADictionary类型对象
2:plist文件的作用
作用:plist是做数据持久化的专业文件,.plist一般情况下用于存储用户密码、临时信息、简介这样的简单
3:Plist文件特点(先将Xcode创建plist文件,再通过创建好的plist文件介绍plist文件特点)
Plist文件特点:
1:Plist文件的根路径只能是数组和字典(Plist文件只能持久化数组和字典)
2:Plist文件的子路径只能是NSString NSNumber NSDate NSData NSArray NSDictionary类的对象内容不能保存其他类型数据
4:Xcode创建plist文件
Plist文件内容的格式是xml语法格式
创建步骤
1.点击File--》New File 弹出一对话框
2.iOS程序选中iOS栏中的Resource/Mac程序选中OS X 栏中的resource
3.点击Resource中的Property List 创建plist文件
4.点击文件中的'+'可以添加数据
5:代码创建和读取plist文件
如果想把NSString NSNumber NSDate NSData NSArray NSDictionary类的对象写入文件中一般用plist文件,但是因为plist文件根路径只能是NSArray和NSDoctionary所以只能持久化NSArray和NSDoctionary对象,这时候就需要将数据保存再数组或字典中然后调用数组和字典的相关方法把数组和字典写入到plist文件中
//将数组和字典写入plist文件的方法
//path:plist文件的路径
//useAuxiliaryFile:是否具有原子性
- (BOOL)writeToFile:(NSString
*)path atomically:(BOOL)useAuxiliaryFile;
//将plist文件读取到数组和字典中
//将plist文件读取到数组中(类方法)
+(id)arrayWithContentsOfFile:(NSString
*)path;
//将plist文件读取到字典中(类方法)
+(id)dictionaryWithContentsOfFile:(NSString *)path
//将数组写入到plist文件中
例子1:创建一个数组,数组成员是NSString类型的对象@“bei”,@“jing”,@“huan”,@“ying”,@“nin”
把该数组持久化到一个plist文件中,并读取plist文件中内容
/*
//将数组写入到plist文件中
例子1:创建一个数组,数组成员是NSString类型的对象@“bei”,@“jing”,@“huan”,@“ying”,@“nin”
把该数组持久化到一个plist文件中,并读取plist文件中内容
*/
void test1(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";
NSArray *array = [NSArray
arrayWithObjects:@"bei",
@"jing", @"huan",
@"ying", @"nin",
nil];
//- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;
//作用:将数组写入plist文件
//path:plist文件路径
//useAuxiliaryFile:是否具有原子性
[array writeToFile:[pathDesktop
stringByAppendingString:@"/arrar1.plist"]
atomically:YES];
NSArray *arrayFromPlist = [NSArray
arrayWithContentsOfFile:[pathDesktop stringByAppendingString:@"/arrar1.plist"]];
NSLog(@"%@", arrayFromPlist);
}
例子2:创建一个数组,数组成员是两个字典对象dictionary1和dictionary2,
dictionary1中有:
@“chen chao”,@“name”
@“18”,@“age”
@“Good Teacher”,@“info”三个键值对(前面是value后面是key)
dictionary2中有:
@“liu de hua”,@“name”
@“56”,@“age”
@“actor”,@“info”三个键值对
把该数组持久化到一个plist文件中,并读取plist文件中内容
void test2(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";
NSDictionary *dictionary1 = [NSDictionary
dictionaryWithObjectsAndKeys:
@"chen chao",
@"name",
@"18",
@"age",
@"Good teacher",
@"info",nil];
NSDictionary *dictionary2 = [NSDictionary
dictionaryWithObjectsAndKeys:
@"liu de hua",
@"name",
@"56",
@"age",
@"actor",
@"info", nil];
NSArray *array = [NSArray
arrayWithObjects:dictionary1, dictionary2,
nil];
[array writeToFile:[pathDesktop
stringByAppendingString:@"/array2.plist"]
atomically:YES];
NSArray *arrayFromPlist = [NSArray
arrayWithContentsOfFile:[pathDesktop stringByAppendingString:@"/array2.plist"]];
NSLog(@"%@", arrayFromPlist);
}
//将字典写入到list文件中
例子3:创建一个字典对象,字典对象中有
@“chen chao”,@“name”
@“18”,@“age”
@“Good Teacher”,@“info”三个键值对
将该字典写入到list文件中,并读取plist文件中内容
void test3(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";
NSDictionary *dictionary = [NSDictionary
dictionaryWithObjectsAndKeys:
@"chen chao",
@"name",
@"18",
@"age",
@"Good teacher",
@"info", nil];
[dictionary writeToFile:[pathDesktop
stringByAppendingString:@"/dictionary1.plist"]
atomically:YES];
NSDictionary *dictionaryFromPlist = [NSDictionary
dictionaryWithContentsOfFile:[pathDesktop
stringByAppendingString:@"/dictionary1.plist"]];
NSLog(@"%@", dictionaryFromPlist);
}
例子4:创建一个字典,字典中有
array1, @“key1”
array2, @“key2”
array3, @“key3”
array4, @“key4”四个键值对
array1数组成员有:@“ni”, @“hao”
array2数组成员有:@“bei”, @“jing”
array3数组成员有:@“huan”
array4数组成员有:@“ying”, @“nin”,@“hao”,@“ma”
将该字典写入到list文件中,并读取plist文件中内容
void test4(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";
NSArray *array1 = [NSArray
arrayWithObjects:@"ni",
@"hao",
nil];
NSArray *array2 = [NSArray
arrayWithObjects:@"bei",
@"jing",
nil];
NSArray *array3 = [NSArray
arrayWithObjects:@"huan",
nil];
NSArray *array4 = [NSArray
arrayWithObjects:@"ying",
@"nin",
@"hao", @"ma",
nil];
NSDictionary *dictionary = [NSDictionary
dictionaryWithObjectsAndKeys:
array1, @"key1",
array2, @"key2",
array3, @"key3",
array4, @"key4",nil];
[dictionary writeToFile:[pathDesktop
stringByAppendingString:@"/dictionary2.plist"]
atomically:YES];
NSDictionary *dictionaryFromPlist = [NSDictionary
dictionaryWithContentsOfFile:[pathDesktop
stringByAppendingString:@"/dictionary2.plist"]];
NSLog(@"%@", dictionaryFromPlist);
}
练习:创建一个字典,字典中有三个元素
@“value1”,@“key1”
@“value2”,@“key2”
array, @“key3”
array是一个数组,数组中有两个字典对象dict1和dict2
dict1和dict2中有
@“value1”,@“key1”
@“value2”,@“key2”
两个键值对
将该字典写入plist文件中并读取
void test5(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";
NSDictionary *dict1 = [NSDictionary
dictionaryWithObjectsAndKeys:
@"value1",
@"key1",
@"value2",
@"key2",nil];
NSDictionary *dict2 = [NSDictionary
dictionaryWithObjectsAndKeys:
@"value1",
@"key1",
@"value2",
@"key2",nil];
NSArray *array = [NSArray
arrayWithObjects:dict1, dict2,
nil];
NSDictionary *dictionary = [NSDictionary
dictionaryWithObjectsAndKeys:
@"value1",
@"key1",
@"value2",
@"key2",
array, @"key3",nil];
[dictionary writeToFile:[pathDesktop
stringByAppendingString:@"/dict.plist"]
atomically:YES];
NSDictionary *dictionaryFromPlist = [NSDictionary
dictionaryWithContentsOfFile:[pathDesktop
stringByAppendingString:@"/dict.plist"]];
NSLog(@"%@", dictionaryFromPlist);
}
归档和反归档
1:什么是归档和反归档
归档:归档就是通过某种格式把内存中的某个对象保存到本地文件中,以便以后再从该文件中读回该对象
反归档:把归档的对象文件读成原来的内存中的对象
2:系统类对象的归档和反归档
系统类归档
//NSKeyedArchiver类的方法
+ (BOOL)archiveRootObject:(id)rootObject toFile:(NSString *)path;
系统类反归档
//NSKeyedUnarchiver类的方法
+ (id)unarchiveObjectWithFile:(NSString
*)path;
1:NSString的归档和反归档
例题:创建一个NSString类对象值为@“bei jing huan ying nin”,将该对象进行归档和反归档
//例题:创建一个NSString类对象值为@“bei jing huan ying nin”,将该对象进行归档和反归档
void test1(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";
NSString *string =
@"1439 best NB";
//+ (BOOL)archiveRootObject:(id)rootObject toFile:(NSString *)path;
//作用:对oc对象进行归档操作
[NSKeyedArchiver
archiveRootObject:string toFile:[pathDesktop
stringByAppendingString:@"/归档文件string"]];
//+ (id)unarchiveObjectWithFile:(NSString *)path;
//作用:对归档文件反归档成oc对象
NSString *stringFromArchiver = [NSKeyedUnarchiver
unarchiveObjectWithFile:[pathDesktop stringByAppendingString:@"/归档文件string"]];
NSLog(@"%@", stringFromArchiver);
}
2:NSArray的归档和反归档
例题:创建一个NSArray类对象值为@“bei”,@“jing”,@“huan”,@“ying”,@“nin”,将该对象进行归档和反归档
//例题:创建一个NSArray类对象值为@“bei”,@“jing”,@“huan”,@“ying”,@“nin”,将该对象进行归档和反归档
void test2(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";
NSArray *array = [NSArray
arrayWithObjects:@"1439",
@"have", @"a",
@"best", @"teacher",
nil];
[NSKeyedArchiver
archiveRootObject:array toFile:[pathDesktop
stringByAppendingString:@"/归档文件array"]];
NSArray *arrayFromArchiver = [NSKeyedUnarchiver
unarchiveObjectWithFile:[pathDesktop stringByAppendingString:@"/归档文件array"]];
NSLog(@"%@", arrayFromArchiver);
}
3:NSDictionary的归档和反归档
例题:创建一个NSDictionary类对象值为
@“value1”, @“key1”
@“value2”, @“key2”
@“value3”, @“key3”三个键值对,将该对象进行归档和反归档
3:自定义类对象的归档和反归档
思考:对于系统类NSString,NSArray, NSDictionary类对象可以直接进行归档和反归档操作,是不是说所有的oc类对象都能进行归档和反归档操作?
不是,只有遵守了<NSCoding>协议的类的对象才能进行归档和反归档操作
如果自定义的类对象要进行归档那么这个对象的属性所属的类也必须要遵守归档协议NSCoding
必须实现以下两个方法:
//归档的时候调用的方法
- (void)encodeWithCoder:(NSCoder *)aCoder;
//解归档的时候要调用的函数
- (id)initWithCoder:(NSCoder *)aDecoder;
例子:创建一个Student类,类中有_age和_name两个实例变量,堆Student类对象进行归档和反归档操作
Student类
Student.h
//对于一个自定义的类想要进行归档和反归档操作必须遵守NSCoding协议
//遵守NSCoding协议
#import <Foundation/Foundation.h>
//.h文件类的声明后面加上<协议名>,表示该类遵守这个协议
@interface Student :
NSObject <NSCoding>
@property (assign,
nonatomic)int age;
@property (copy,
nonatomic)NSString *name;
//协议中的内容
- (void)encodeWithCoder:(NSCoder *)aCoder;//归档操作的时候自动被调用
- (id)initWithCoder:(NSCoder *)aDecoder;//反归档的时候自动被调用
@end
Student.m
//.m实现协议中的方法
#import "Student.h"
@implementation Student
//归档的时候调用
- (void)encodeWithCoder:(NSCoder *)aCoder{
//- (void)encodeInt:(int)intv forKey:(NSString *)key;
//作用:归档int类型的数据
//key:归档的格式,归档格式任意但是以什么格式归档就需要以什么格式反归档
[aCoder encodeInt:self.age
forKey:@"age"];
//- (void)encodeObject:(id)objv forKey:(NSString *)key;
//作用:归档oc对象
[aCoder encodeObject:self.name
forKey:@"name"];
}
- (id)initWithCoder:(NSCoder *)aDecoder{
//- (int)decodeIntForKey:(NSString *)key;
//作用:反归档int类型数据
self.age = [aDecoder
decodeIntForKey:@"age"];
self.name = [aDecoder
decodeObjectForKey:@"name"];
return
self;
}
@end
main.m
#import <Foundation/Foundation.h>
#import "Student.h"
int main(int argc,
const char * argv[])
{
@autoreleasepool {
NSString *pathDesktop =
@"/Users/mac/Desktop";
Student *std = [[Student
alloc] init];
std.age =
10;
std.name =
@"xiao xin";
[NSKeyedArchiver
archiveRootObject:std toFile:[pathDesktop
stringByAppendingString:@"/归档文件student"]];
Student *stdFromArchiver = [NSKeyedUnarchiver
unarchiveObjectWithFile:[pathDesktop stringByAppendingString:@"/归档文件student"]];
NSLog(@"age is %d name is %@", stdFromArchiver.age, stdFromArchiver.name);
}
return 0;
}
练习:创建一个Person类,累中有_age和_name两个实例变量,实现Person类对象的归档和反归档
JSON
1:什么是json
json时一种轻量级的数据格式,用于数据交互
服务器返回给客户端的数据,一般都是JSON格式或者XML格式(文件下载除外)
2:json的作用
json可以将javaScript对象中表示的一组数据转换成字符串,然后就可以在函数之间轻松的传递这个字符串,或者在异步应用程序中将字符串从Web客户机传递给服务端程序,这个字符串看起来有点儿古怪,但是JavaScript很容易解释它,而且JSON可以表示比“名称/值对”更复杂的结构。例如,可以表示数组和复杂对象,而不仅时键和值的简单列表。
3:json中的基本语法
名称/值对包括字段名称(在双引号中),后面写一个冒号,然后是值。
如:“firstName”:“Tom”
4:json的值
JSON的值可以是:
1:数字(整数或浮点数)
2:字符串(双引号中)
3:逻辑值(true或false)
4:数组([]中)
5:对象({}中)
JSON – OC
转换对照表
5:JSON的结构
JSON最外曾通常有数组和字典两种结构,通过这两种结构可以表示各种复杂的结构
1:数组:数组在json中是中括号‘[]’括起来的内容,数据结构为["java","javascript","vb",…],类似于OC中的数组
2:对象:对象在json中表示为“{}”括起来的内容,数据结构为 {key:value,key:value,…}的键值对的结构,类似于oc中的字典结构
json的结构也决定了json最终只能转换成数组或字典类型的对象
@{key : value}
例如:
{
"count" : 30,
"totalcount" : "51708",
"users" : [
{
"credit" : "803",
"experience" : "680",
"friendnum" : "19",
"groupid" : "6",
"headimage" : "/my/headimage.php?uid=50519",
"lastactivity" : "1402365234",
"realname" : "曉樂",
"uid" : "50519",
"username" : "魚曉樂",
"viewnum" : "210"
},
{
"credit" : "111",
"experience" : "736",
"friendnum" : "25",
"groupid" : "6",
"headimage" : "/my/headimage.php?uid=50972",
"lastactivity" : 0,
"realname" : "啊啊啊",
"uid" : "50972",
"username" : "小爪冰凉",
"viewnum" : "86"
},
]
}
分析:最外层大括号括起来说明json是字典,字典中有三个键值对,"count”对应的value是NSNumber,"totalcount" 对应的value是NSString,"users" 对应的value是一个数组,并且该数组成员是两个字典
6:JSON解析
JSON解析方案
1.在iOS中,JSON的常见解析方案有4种
(1)第三方框架:JSONKit、SBJson、TouchJSON(性能从左到右,越差)
(2)苹果原生(自带):NSJSONSerialization(性能最好)
json文件解析(analysis)
本地json解析步骤:
1:首先调用NSString的
+ (id)stringWithContentsOfFile:(NSString
*)path encoding:(NSStringEncoding)enc error:(NSError **)error;
方法将文件读成字符串
2:然后调用NSString的
- (NSData *)dataUsingEncoding:(NSStringEncoding)encoding;
把字符串转换成NSData二进制数据
3:调用系统类NSJSONSerialization的
+ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt
error:(NSError **)error;
方法进行解析,最后解析为NSArray或者NSDictionary
例子:对本地jsonUserList.txt文件进行解析
//json文件的解析
void JsonAnalysis1(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";
//1:读取json文件内容保存在string
NSString *string = [NSString
stringWithContentsOfFile:[pathDesktop stringByAppendingString:@"/json/jsonUserList.txt"]
encoding:NSUTF8StringEncoding
error:nil];
//2:把string转换成data
NSData *dataFromString = [string
dataUsingEncoding:NSUTF8StringEncoding];
//3:将data进行json解析
NSDictionary *dictionary = [NSJSONSerialization
JSONObjectWithData:dataFromString options:NSJSONReadingMutableContainers
error:nil];
NSLog(@"%@", dictionary);
}
练习:对本地json.txt文件进行解析
void JsonAnalysis2(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";
NSString *string = [NSString
stringWithContentsOfFile:[pathDesktop stringByAppendingString:@"/json/json.txt"]
encoding:NSUTF8StringEncoding
error:nil];
NSData *dataFromString = [string
dataUsingEncoding:NSUTF8StringEncoding];
NSArray *array = [NSJSONSerialization
JSONObjectWithData:dataFromString options:NSJSONReadingMutableContainers
error:nil];
NSLog(@"%@", array);
}
练习:
1:创建一个数组,数组成员是两个字典对象dictionary1和dictionary2,和一个数组对象array3
dictionary1中有:
@“chen chao”,@“name”
@“18”,@“age”
@“Good Teacher”,@“info”三个键值对(前面是value后面是key)
dictionary2中有:
@“liu de hua”,@“name”
@“56”,@“age”
@“actor”,@“info”三个键值对
array3成员是@“bei”,@“jing”,@“huan”,@“ying”,@“nin”
把该数组持久化到一个plist文件中,并读取plist文件中内容
2:创建一个字典,字典中有
array1, @“key1”
array2, @“key2”
dictionary3, @“key3”
array4, @“key4”四个键值对
array1数组成员有:@“ni”, @“hao”
array2数组成员有:@“bei”, @“jing”
dictionary3中有:
@“liu de hua”,@“name”
@“56”,@“age”
@“actor”,@“info”三个键值对
array4数组成员有:@“ying”, @“nin”,@“hao”,@“ma”
将该字典写入到list文件中,并读取plist文件中内容
3:分别创建一个NSString和NSArray和NSDictionary对象,并对该对象进行归档和反归档操作
4:创建一个自定义Person,成员是age和name,实现person类对象的归档反归档
ww文件和目录的操作和管理的基本知识
1:什么是文件和目录
文件:file
目录:dir
2:单例模式
1:什么是单例模式
单例模式是一种常见的设计模式,对于单例对象的类,必须要保证在任意时刻下只有一个对象存在,而且自行实例化该对象,并向整个系统提供这个对象。也就是说对于一个单例类无论实例化对象多少次都只有一个实例对象存在,并且这个对象是全局的,能够被整个系统访问到。
单例对象和c中的全局变量很相似。c中的全局变量可以实现在不同函数之间的数据共享,单例对象可以实现在不同对象之间的数据共享
2:单例对象的创建方式
一般类方式,并且
shared/default/current 开头
3:单例模式的应用
1:在不同对象之间数据共享
2:当创建一个类的时候需要耗费很大的性能时,这时候可以把这个类设计成单例类
3:Xcode中自己创建一个单例类
例子:
创建一个NormalClass类,类中有属性name,实例化出两个对象,给对象一的name赋值,打印两个对象的地址和属性值
创建一个SingleClass类,类中有属性name,实例化出两个对象,给对象一的name赋值,打印两个对象的地址和属性值
NormalClass类
NormalClass.h
#import <Foundation/Foundation.h>
@interface NormalClass :
NSObject
@property (copy,
nonatomic)NSString *name;
@end
NormalClass.m
#import "NormalClass.h"
@implementation NormalClass
@end
SingleClass类
SingleClass.h
#import <Foundation/Foundation.h>
@interface SingleClass :
NSObject
@property (copy,
nonatomic)NSString *name;
+ (SingleClass *)sharedSingleClass;//创建单例对象的方法
@end
SingleClass.m
#import "SingleClass.h"
//1:创建一个静态的全局单例对象并且初始化为nil
static SingleClass *single =
nil;
@implementation SingleClass
+ (SingleClass *)sharedSingleClass{
//2:调用GCD的once方法
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{//block//保证{}里面的代码在整个程序运行期间只被执行一次
//3:对象单例对象进行实例化
single = [[SingleClass
alloc] init];
});
return
single;//第一次调用该方法的时候返回实例化后的对象//从第二次开始返回的都是第一次实例化的对象
}
main.m
#import <Foundation/Foundation.h>
#import "NormalClass.h"
#import "SingleClass.h"
int main(int argc,
const char * argv[])
{
@autoreleasepool {
NormalClass *normal1 = [[NormalClass
alloc] init];//实例化对象
NormalClass *normal2 = [[NormalClass
alloc] init];
//1:打印两个对象的地址值不同,说明这两个对象是不同的对象
NSLog(@"normal1 = %p", normal1);
NSLog(@"normal2 = %p", normal2);
//2:修改某个对象的实例变量值,对另一个对象没有影响,说明这是两个不同的对象
normal1.name =
@"chen chao";
NSLog(@"normal1.name = %@", normal1.name);
NSLog(@"normal2.name = %@", normal2.name);
SingleClass *single1 = [SingleClass
sharedSingleClass];//创建单例对象
SingleClass *single2 = [SingleClass
sharedSingleClass];//创建单例对象
//1:打印两个单例类对象地址相同,说明这两个是同一个对象
NSLog(@"single1 = %p", single1);
NSLog(@"single2 = %p", single2);
//修改某个对象的值,另个对象也跟着一起改,说明两个对象是同一个对象
single1.name =
@"chen chao";
NSLog(@"single1.name = %@", single1.name);
NSLog(@"single2.name = %@", single2.name);
}
return 0;
}
练习:
创建一个PersonNormal非单例类,有一个两个属性int _age和NSString *_name;请用这个非单例的Person类创建两个对象,给一个对象的age和name属性赋值,通过打印观察是否影响另一个对象的值,并打印两个对象的地址
创建一个PersonSingle单例类,有一个两个属性int _age和NSString *_name;请用这个非单例的Person类创建两个对象,给一个对象的age和name属性赋值,通过打印观察是否影响另一个对象的值,并打印两个对象的地址
PersonNormal类
PersonNormal.h
#import <Foundation/Foundation.h>
@interface PersonNormal :
NSObject
@property (assign,
nonatomic)int age;
@property (copy,
nonatomic)NSString *name;
@end
PersonNormal.m
#import "PersonNormal.h"
@implementation PersonNormal
@end
PersonSingle类
PersonSingle.h
#import <Foundation/Foundation.h>
@interface PersonSingle :
NSObject
@property (assign,
nonatomic)int age;
@property (copy,
nonatomic)NSString *name;
+ (id)sharedPersonSingle;
@end
PersonSingle.m
#import "PersonSingle.h"
static PersonSingle *single =
nil;
@implementation PersonSingle
+ (id)sharedPersonSingle{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{//block
single = [[PersonSingle
alloc] init];
});
return single;
}
@end
main.m
#import <Foundation/Foundation.h>
#import "PersonNormal.h"
#import "PersonSingle.h"
int main(int argc,
const char * argv[])
{
@autoreleasepool {
PersonNormal *normal1 = [[PersonNormal
alloc] init];
PersonNormal *normal2 = [[PersonNormal
alloc] init];
NSLog(@"normal1 = %p", normal1);
NSLog(@"normal2 = %p", normal2);
normal1.age =
18;
normal1.name =
@"chen chao";
NSLog(@"normal1.age is %d normal1.name is %@", normal1.age,
normal1.name);
NSLog(@"normal2.age is %d normal2.name is %@", normal2.age,
normal2.name);
PersonSingle *single1 = [PersonSingle
sharedPersonSingle];
PersonSingle *single2 = [PersonSingle
sharedPersonSingle];
NSLog(@"single1 = %p", single1);
NSLog(@"single2 = %p", single2);
single1.age =
56;
single1.name =
@"zhang xue you";
NSLog(@"single1.age is %d single1.name is %@", single1.age,
single1.name);
NSLog(@"single2.age is %d single2.name is %@", single2.age,
single2.name);
}
return 0;
}
NSData和NSString之间的互相转换
#import <Foundation/Foundation.h>
int main(int argc,
const char * argv[])
{
@autoreleasepool {
NSString *string =
@"bei jing huan ying nin";
//- (NSData *)dataUsingEncoding:(NSStringEncoding)encoding; // External representation
//作用:将string转换成data
//encoding:编码格式
NSData *dataFromString = [string
dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"dataFromString = %@", dataFromString);
//- (instancetype)initWithData:(NSData *)data encoding:(NSStringEncoding)encoding;
//作用:将string转换成data
NSString *stringFromData = [[NSString
alloc] initWithData:dataFromString
encoding:NSUTF8StringEncoding];
NSLog(@"stringFromData = %@", stringFromData);
}
return 0;
}
文件和目录管理
1:什么文件和目录管理
文件目录管理:就是指文件和目录的创建,目录的遍历,文件目录的复制,剪切,删除等
2:文件管理器对象的创建(单例对象)
NSFileManager * fm = [NSFileManager
defaultManager];
//文件管理器的创建
void createFileManage(void){
//fileManage对象一旦创建完成后,后续所有的文件操作都是通过fileManage进行操作的
NSFileManager *fileManage = [NSFileManager
defaultManager];//创建一个单例类的对象
}
3:文件和目录的创建
//创建普通文件//如果两个文件的文件名相同时,创建成功,但是会用新文件覆盖旧的文件
- (BOOL)createFileAtPath:(NSString
*)path contents:(NSData *)data attributes:(NSDictionary *)attr;
//创建目录//第二个参数是:当子路径不存在时是否创建子路径
- (BOOL)createDirectoryAtPath:(NSString
*)path withIntermediateDirectories:(BOOL)createIntermediates attributes:(NSDictionary *)attributes error:(NSError **)error ;
//文件和目录的创建
void createFileAndDir(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileManager *fileManage = [NSFileManager
defaultManager];
//- (BOOL)createFileAtPath:(NSString *)path contents:(NSData *)data attributes:(NSDictionary *)attr;
//作用:创建文件
//path:创建的文件路径
//data:创建文件开始时给文件添加内容,如果时nil,创建的文件就是空文件
//attr:文件属性
[fileManage createFileAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]
contents:nil
attributes:nil];
//- (BOOL)createDirectoryAtPath:(NSString *)path withIntermediateDirectories:(BOOL)createIntermediates attributes:(NSDictionary *)attributes error:(NSError **)error NS_AVAILABLE(10_5, 2_0);
//作用:创建目录
//path:目录的路径
//createIntermediates:如果创建的路径的子路径不存在时,是否连同子路径一起创建
//attributes:文件属性
//error:如果创建失败,保存创建失败的原因
NSError *error =
nil;
[fileManage createDirectoryAtPath:[pathDesktop
stringByAppendingString:@"/dir/dir1"]
withIntermediateDirectories:NO
attributes:nil
error:&error];
if (error) {
NSLog(@"创建目录失败 : %@",
[error localizedFailureReason]);
}
}
withIntermediateDirectories:NO
如果是no的话没有路径中没有dir文件或者目录,则不能完成创建dir1,如果是YES,则自动创建路径包含的中间的文件夹dir
4:目录的遍历(traverse)
//浅度遍历
- (NSArray *)contentsOfDirectoryAtPath:(NSString
*)path error:(NSError **)error;
//深度遍历
- (NSArray *)subpathsOfDirectoryAtPath:(NSString
*)path error:(NSError **)error
//目录的遍历
void traverseDir(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileManager *fileManage = [NSFileManager
defaultManager];
//- (NSArray *)contentsOfDirectoryAtPath:(NSString *)path error:(NSError **)error NS_AVAILABLE(10_5, 2_0);
//作用:浅层遍历,只能遍历一层
NSArray *arrayContent = [fileManage
contentsOfDirectoryAtPath:[pathDesktop
stringByAppendingString:@"/dir"]
error:nil];
NSLog(@"%@", arrayContent);
//- (NSArray *)subpathsOfDirectoryAtPath:(NSString *)path error:(NSError **)error NS_AVAILABLE(10_5, 2_0);
//作用:深层遍历,一直遍历到最后一层
NSArray *arraySub = [fileManage
subpathsOfDirectoryAtPath:[pathDesktop
stringByAppendingString:@"/dir"]
error:nil];
NSLog(@"%@", arraySub);
}
练习1:深层遍历目录下所有文件,并找出以.txt为后缀的文件,将文件名输出
//练习1:深层遍历目录下所有文件,并找出以.txt为后缀的文件,将文件名输出
void test1(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileManager *fileManage = [NSFileManager
defaultManager];
NSArray *arraySub = [fileManage
subpathsOfDirectoryAtPath:[pathDesktop
stringByAppendingString:@"/dir"]
error:nil];//保存所有文件的文件名
for (NSString *fileName
in arraySub) {
if ([fileName
hasSuffix:@"txt"]) {
NSLog(@"%@", fileName);
}
}
}
5:复制文件和目录
//srcPath:原文件路径
//dstPath:新文件路径
- (BOOL)copyItemAtPath:(NSString
*)srcPath toPath:(NSString *)dstPath error:(NSError **)error ;
//复制文件或目录
void copyFileAndDir(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileManager *fileManage = [NSFileManager
defaultManager];
//- (BOOL)copyItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error NS_AVAILABLE(10_5, 2_0);
//作用:文件或目录的复制
//复制文件
[fileManage copyItemAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]
toPath:[pathDesktop stringByAppendingString:@"/dir/fileCopy.txt"]
error:nil];
[fileManage copyItemAtPath:[pathDesktop
stringByAppendingString:@"/dir/dir1"]
toPath:[pathDesktop stringByAppendingString:@"/dir1Copy"]
error:nil];
}
6:剪切(cut)文件和目录
- (BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString
*)dstPath error:(NSError **)error ;
//剪切文件或目录
void cutFileAndDir(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileManager *fileManage = [NSFileManager
defaultManager];
//- (BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error NS_AVAILABLE(10_5, 2_0);
//作用:剪切文件或目录
[fileManage moveItemAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]
toPath:[pathDesktop stringByAppendingString:@"/dir/dir1/fileCut.txt"]
error:nil];
}
7:删除文件和目录
- (BOOL)removeItemAtPath:(NSString
*)path error:(NSError **)error;
//删除文件或目录
void deleteFileAndDir(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileManager *fileManage = [NSFileManager
defaultManager];
//- (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error NS_AVAILABLE(10_5, 2_0);
//作用:删除文件或目录
[fileManage removeItemAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]
error:nil];
}
8:获取文件属性(attribute)
- (NSDictionary *)attributesOfItemAtPath:(NSString
*)path error:(NSError **)error;
//获取文件的属性
void getAttribute(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileManager *fileManage = [NSFileManager
defaultManager];//创建单例对象
//- (NSDictionary *)attributesOfItemAtPath:(NSString *)path error:(NSError **)error NS_AVAILABLE(10_5, 2_0);
//作用:获取文件或目录的相关属性
NSDictionary *dictionaryFile = [fileManage
attributesOfItemAtPath:[pathDesktop stringByAppendingString:@"/file.txt"]
error:nil];
NSDictionary *dictionaryDir = [fileManage
attributesOfItemAtPath:[pathDesktop stringByAppendingString:@"/dir"]
error:nil];
NSLog(@"%@", dictionaryFile);
NSLog(@"%@", dictionaryDir);
}
9:判断文件是否存在
- (BOOL)fileExistsAtPath:(NSString
*)path;
//判断文件是否存在
void isHaveFileOrDir(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileManager *fileManage = [NSFileManager
defaultManager];//创建单例对象
if ([fileManage
fileExistsAtPath:[pathDesktop stringByAppendingString:@"/file.txt"]]) {
NSLog(@"有这个文件");
} else {
NSLog(@"没有这个文件");
}
}
练习2:打印目录下所有文件和目录的大小(包括子路径下的文件和目录)。
//练习2:打印目录下所有文件和目录的大小(包括子路径下的文件和目录)。
void test2(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileManager *fileManage = [NSFileManager
defaultManager];//创建单例对象
//遍历所有子目录(深层遍历)
NSArray *arraySub = [fileManage
subpathsOfDirectoryAtPath:[pathDesktop
stringByAppendingString:@"/dir"]
error:nil];
for (NSString *fileName
in arraySub) {//取出每个文件或目录
NSLog(@"%@", fileName);
NSDictionary *dictionary = [fileManage
attributesOfItemAtPath:[[[pathDesktop stringByAppendingString:@"/dir"]
stringByAppendingString:@"/"]
stringByAppendingString:fileName] error:nil];
NSLog(@"%@", [dictionary
objectForKey:@"NSFileSize"]);
}
}
练习3:
1:创建一个文件夹dir
2:创建一个文件file.txt
create
3:将file.txt复制一份带dir中,复制后文件叫fileCopy.txt
copy
4:将file.txt剪切一份带dir中,复制后文件叫fileCut.txt
move
5:遍历dir下所有文件,打印每个文件的所有属性信息,并提出出文件大小
sub
/*
练习3:
1:创建一个文件夹dir
2:创建一个文件file.txt
create
3:将file.txt复制一份带dir中,复制后文件叫fileCopy.txt
copy
4:将file.txt剪切一份带dir中,复制后文件叫fileCut.txt
move
5:遍历dir下所有文件,打印每个文件的所有属性信息,并提出出文件大小
sub
*/
void test4(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileManager *fileManage = [NSFileManager
defaultManager];//创建单例对象
//1:创建文件夹dir
[fileManage createDirectoryAtPath:[pathDesktop
stringByAppendingString:@"/dir"]
withIntermediateDirectories:YES
attributes:nil
error:nil];
//2:创建文件file.txt
[fileManage createFileAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]
contents:nil
attributes:nil];
//3:将file.txt复制一份带dir中,复制后文件叫fileCopy.txt
[fileManage copyItemAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]
toPath:[pathDesktop stringByAppendingString:@"/dir/fileCopy.txt"]
error:nil];
//4:将file.txt剪切一份带dir中,复制后文件叫fileCut.txt
[fileManage moveItemAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]
toPath:[pathDesktop stringByAppendingString:@"/dir/fileCut.txt"]
error:nil];
}
文件操作
1:什么是文件操作
文件操作:就是指对文件的打开,文件内容的读、写、设置偏移量和同步
2:文件的打开
//以只读方式打开
+ (id)fileHandleForReadingAtPath:(NSString *)path;
//以只写方式打开
+ (id)fileHandleForWritingAtPath:(NSString *)path;
//以读写方式打开
+ (id)fileHandleForUpdatingAtPath:(NSString *)path;
//文件的打开
void openFile(void){
//注意:NSFileHandle对象创建完成后,后续所有对文件内的操作都是通过NSFileHandle对象来完成的
NSString *pathDesktop =
@"/Users/mac/Desktop";
//+ (id)fileHandleForReadingAtPath:(NSString *)path;
//作用:以只读的方式打开文件
NSFileHandle *fileHandleRead = [NSFileHandle
fileHandleForReadingAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]];
//+ (id)fileHandleForWritingAtPath:(NSString *)path;
//作用:以只写的方式打开文件
NSFileHandle *fileHandleWrite = [NSFileHandle
fileHandleForWritingAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]];
//+ (id)fileHandleForUpdatingAtPath:(NSString *)path;
//作用:以读写的方式打开文件
NSFileHandle *fileHandleUp = [NSFileHandle
fileHandleForUpdatingAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]];
}
3:文件内容的读取
1:读取指定长度的数据
- (NSData *)readDataOfLength:(NSUInteger)length;
2:从当前偏移量读到文件末尾
- (NSData *)readDataToEndOfFile;
//文件内容的读取
void readFile(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileHandle *fileHandle = [NSFileHandle
fileHandleForUpdatingAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]];//以读写的方式打开文件
#if 0
//- (NSData *)readDataOfLength:(NSUInteger)length;
//作用:读取文件中指定长度的数据
NSData *dataFromFile = [fileHandle readDataOfLength:6];
NSString *stringFromData = [[NSString alloc] initWithData:dataFromFile encoding:NSUTF8StringEncoding];//把data转换成string
NSLog(@"%@", stringFromData);
#endif
//- (NSData *)readDataToEndOfFile;
//作用:读取文件中所有的数据
NSData *dataFromFile = [fileHandle
readDataToEndOfFile];
NSString *stringFromData = [[NSString
alloc] initWithData:dataFromFile
encoding:NSUTF8StringEncoding];
NSLog(@"%@", stringFromData);
}
4:写文件
- (void)writeData:(NSData
*)data;
//向文件中写数据
void writeDataToFile(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileHandle *fileHandle = [NSFileHandle
fileHandleForUpdatingAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]];//以读写的方式打开文件
NSString *string =
@"chen chao zui shuai";
NSData *dataFromString = [string
dataUsingEncoding:NSUTF8StringEncoding];//将string转换成data
//- (void)writeData:(NSData *)data;
//作用:向文件中写数据(覆盖之前内容)
[fileHandle writeData: dataFromString];
//思考:文件末尾出写入@"chen chao ni zui shuai"
NSLog(@"%@", [[NSString
alloc] initWithData:[fileHandle
readDataOfLength:5]
encoding:NSUTF8StringEncoding]);
}
思考:如果想在文件末尾添加内容时,该如何处理?
5:设置文件偏移量
1:将文件偏移量设置到文件中的指定位置
- (void)seekToFileOffset:(unsigned
long long)offset;
2:将文件偏移量设置到文件末尾
- (unsigned
long long)seekToEndOfFile;
//设置文件偏移量
void setFileSeek(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileHandle *fileHandle = [NSFileHandle
fileHandleForUpdatingAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]];//以读写的方式打开文件
[fileHandle seekToFileOffset:5];//设置文件偏移量到指定位置
[fileHandle seekToEndOfFile];//设置文件偏移量到文件末尾
NSLog(@"%@", [[NSString
alloc] initWithData:[fileHandle
readDataOfLength:4]
encoding:NSUTF8StringEncoding]);
}
练习3:在文件末尾写入新的信息并将整个文件内容读取后输出
//1:打开文件
//2:设置便宜量到文件末尾
//3:写入数据
//4:设置偏移量到文件开始
//5:读取文件内容
void test3(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";
//1:打开文件
NSFileHandle *fileHandle = [NSFileHandle
fileHandleForUpdatingAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]];
//2:设置便宜量到文件末尾
[fileHandle seekToEndOfFile];
//3:写入数据
NSString *string =
@"liu de hua mei wo shuai";
NSData *dataFromString = [string
dataUsingEncoding:NSUTF8StringEncoding];
[fileHandle writeData:dataFromString];
//4:设置偏移量到文件开始
[fileHandle seekToFileOffset:0];
//5:读取文件内容
NSData *dataFromFile = [fileHandle
readDataToEndOfFile];
NSString *stringFromData = [[NSString
alloc] initWithData:dataFromFile
encoding:NSUTF8StringEncoding];
NSLog(@"%@", stringFromData);
}
练习4:在文件开始处和文件末尾处添加字符串@“chen chao ni zui shuai”,添加完成后读取文件所有内容并输出
sdkljfhslkdfjgl
//1:打开文件
//2:读取文件中所有内容
//3:拼接
//4:设置偏移量到文件开始
//5:写入拼接后的信息
//6:写入字符串
//7:设置偏移量到文件开始
//8:读取文件内容
/*
练习4:在文件开始处和文件末尾处添加字符串@“chen chao ni zui shuai”,添加完成后读取文件所有内容并输出
sdkljfhslkdfjgl
//1:打开文件
//2:读取文件中所有内容
//3:拼接
//4:设置偏移量到文件开始
//5:写入拼接后的信息
//6:写入字符串
//7:设置偏移量到文件开始
//8:读取文件内容
*/
void test5(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";
//1:打开文件
NSFileHandle *fileHandle = [NSFileHandle
fileHandleForUpdatingAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]];
//2:读取文件中所有内容
NSData *dataFromFile = [fileHandle
readDataToEndOfFile];
//3:拼接
NSString *string =
@"chen chao ni zui shuai";
NSString *stringFromData = [[NSString
alloc] initWithData:dataFromFile
encoding:NSUTF8StringEncoding];
NSString *stringToFile = [string
stringByAppendingString:stringFromData];
//4:设置偏移量到文件开始
[fileHandle seekToFileOffset:0];
//5:写入拼接后的信息
NSData *dataToFile = [stringToFile
dataUsingEncoding:NSUTF8StringEncoding];
[fileHandle writeData:dataToFile];
//6:写入字符串
NSData *dataToFileString = [string
dataUsingEncoding:NSUTF8StringEncoding];
[fileHandle writeData:dataToFileString];
//7:设置偏移量到文件开始
[fileHandle seekToFileOffset:0];
//8:读取文件内容
NSData *dataFromFileAll = [fileHandle
readDataToEndOfFile];
NSString *stringAll = [[NSString
alloc] initWithData:dataFromFileAll
encoding:NSUTF8StringEncoding];
NSLog(@"%@", stringAll);
}
课后练习:
练习1:创建一个Human单例类
练习2:把字符串@“chen chao”变成NSData类型对象,并将NSData对象转换成NSString后输出
#import <Foundation/Foundation.h>
int main(int argc,
const char * argv[])
{
@autoreleasepool {
NSString *string =
@"chen chao";
NSData *dataFromString = [string
dataUsingEncoding:NSUTF8StringEncoding];//将字符串转成NSData
NSString *stringFromData = [[NSString
alloc] initWithData:dataFromString
encoding:NSUTF8StringEncoding];//将NSData对象转换成字符串
NSLog(@"string = %@", string);
NSLog(@"stringFromData = %@", stringFromData);
}
return 0;
}
练习3:在桌面上创建一个temp文件夹和file.txt文件,将file.txt剪切到temp文件夹下,将字符串@“chen chao ni zui shuai”写入到文件file.txt,并读取文件内容,输出
void test5(void){
//创建文件管理器
NSString *pathDestop =
@"/Users/mac/Desktop";
NSFileManager *fileManage = [NSFileManager
defaultManager];
//创建目录
[fileManage createDirectoryAtPath:[pathDestop
stringByAppendingString:@"/temp"]
withIntermediateDirectories:YES
attributes:nil
error:nil];
//创建文件
[fileManage createFileAtPath:[pathDestop
stringByAppendingString:@"/file.txt"]
contents:nil
attributes:nil];
//将文件剪切到tmp目录下
[fileManage moveItemAtPath:[pathDestop
stringByAppendingString:@"/file.txt"]
toPath:[pathDestop stringByAppendingString:@"/temp/file.txt"]
error:nil];
//创建文件操作
NSFileHandle *fileHandle = [NSFileHandle
fileHandleForUpdatingAtPath:[pathDestop
stringByAppendingString:@"/temp/file.txt"]];
//将字符串写入文件
NSString *string =
@"chen chao ni zui shuai";
NSData *data = [string
dataUsingEncoding:NSUTF8StringEncoding];
[fileHandle writeData:data];
//将文件偏移量设置到文件开始处
[fileHandle seekToFileOffset:0];
//读取文件信息
NSData *dataFromFile = [fileHandle
readDataToEndOfFile];
NSString *stringFromData = [[NSString
alloc] initWithData:dataFromFile
encoding:NSUTF8StringEncoding];
NSLog(@"%@", stringFromData);
}
一、做一个单例
1、做一个单例类,SingleClass
2、singleClass有一个属性,_name(NSString)
3、做一个普通类 NormalClass
4、NormalClass有一个属性,_name(NSString)
5、分别实例化出两个单例类和普通类对象,分别给一个对象的name赋值,打印两个对象的地址和成员值进行比较,总结单例的特点
二、有一个字符串@“123”,把这个字符串转为data,再转回字符串
三、
1、在桌面上创建一个文件夹“page”
2、在page文件夹中创建一个文件夹“my”
3、在my文件夹中,创建一个文件“book.txt”
4、把“book.txt”复制到page文件夹中
5、深度遍历page文件夹并打印
四、
1、在Documents中创建一个文件“class1435.txt”
2、读写方式打开class1435.txt并write“我是中国人”进去
3、把偏移量挪回开头,并读出这个文件字符串内容
4、把文件中的字符串“我是中国人”改成“我还是中国人”
5、读出整个文件字符串内容
五、
遍历桌面上的dir目录,找出里面所有已.txt路径结尾文件,并且读取文件所有信息
———————————————————————————
内存管理
在内存中干3件事:
1、开辟存储空间
2、初始化成员变量
3、返回指针地址
内存回收机制:
手动引用计数和自动释放池
自动引用计数(ARC)
自动垃圾回收(iOS系统不支持垃圾回收
ARC:ARC机制管理内存,它的弊端:系统无法正确识别自定义对象是否还会继续使用,会提前释放,导致程序崩溃
gar— —>object-C atomic Refrence— —>BOOL
MRC:
内存管理黄金法则:
1、关键字:alloc , retain, [mutable] copy, new
2、谁持有,谁管理(/谁污染,谁治理)
autorelease:做的是入池工作 ——》autoreleasepool
在手动引用计数中,改变对象的引用计数的方式如下:
当程序调用方法名以alloc、new、copy、 mutableCopy开头的方法来创建对象时,该对象的引用计数加1。
retain:将该对象的引用计数器加1
release:将该对象的引用计数器减1
autorelease:不改变该对象的引用计数器的值,只是将对象添加到自动释放池中
retainCount:返回该对象的引用计数的值
内存管理:
基本数据 assign【默认参数】非OC对象类型可以使用
对象 retain//保留对象的所有权 OC的对象类型使用+1
字符串 copy NSString类型
arc:
strong的含义和retain相同,weak和assign相同,修饰完的属性变量用法也是完全没有改变,不过strong和weak只能修饰对象。
线程方面:
nonatomic 线程不安【默认参数】
atomic 线程安全
方法生成
readonly
readwrite【默认参数】
@property修饰符展开
assign:直接赋值,不做任何内存管理(默认,用于非oc对象)
retain: release旧值,retain新值(用于oc对象)
copy:release旧值,copy新值(一般用于string )
______________________________________________
KVC(key value coding)
【对象 setValue:(id) forKey:(NSString *)】;
KVO(key value observe观察)
监听
MVC
架构模式(设计模式)
M 模型 数据模型 数据逻辑 网络处理
C 视图控制器
V 视图 展示UI 交互 UILable/UIButton……
——————————————————————————————
//日期与时间(NSDate)
//date当前日期
NSDate *date=[NSDate
date];
NSLog(@"当前时间:%@",date);
//date1 date2
从当前时间开始,一天后的日期
NSDate * date1=[[NSDate
alloc]initWithTimeInterval:3600*24
sinceDate:date];
NSLog(@"当前时间:%@",date1);
NSDate * date2=[[NSDate
alloc]initWithTimeIntervalSinceNow:3600*24];
NSLog(@"当前时间:%@",date2);
//获取当前时间,3天之前的日期
NSDate * date3=[[NSDate
alloc]initWithTimeIntervalSinceNow:-3*3600*24];
NSLog(@"当前时间:%@",date3);
//获取从1970年1月1日开始,20年之后的日期
NSDate * date4=[[NSDate
alloc]initWithTimeIntervalSince1970:3600*24*366*20];
NSLog(@"从1970年1月1日开始,20年之后的日期%@",date4);
//获取对应时间的字符串
NSLocale *cn=[NSLocale
currentLocale];
NSLog(@"对应时间的字符串%@",
[date descriptionWithLocale:cn]);
NSLocale代表一个语言、国际环境(比如大陆的简体中文)
//获取两个日期之间较早的日期
NSData *earlier=[date
earlierDate:date4];;
NSLog(@"两个日期之间较早的日期:%@",earlier);
//获取两个日期之间较晚的日期
NSData *later=[date
laterDate:date1];
NSLog(@"两个日期之间较晚的日期%@",later);
//date
和date1之间的时间差
NSLog(@"两个时间之间的时间差%g秒",[date
timeIntervalSinceDate:date1]);
//获取指定时间与现在的时间差
NSLog(@"指定时间与现在的时间差%g秒",[date1
timeIntervalSinceNow]);
ter);
//日期格式器(NSDateFormatter)
//date当前日期
NSDate *dt=[NSDate
date];
NSLog(@"当前时间:%@",dt);
//分别代表中国
美国
NSLocale *locales[]={[[NSLocale
alloc]initWithLocaleIdentifier:@"中国时间:"],[[NSLocale
alloc]initWithLocaleIdentifier:@"美国时间:"]};
NSDateFormatter *df[8];
//为上面2个NSLocale创建8个DateFormat对象
for (int i=0; i<2; i++) {
df[i*4]=[[NSDateFormatter
alloc]init];
//设置NSDateFormatter的日期、时间风格
[df[i*4]setDateStyle:NSDateFormatterShortStyle];
[df[i*4]setTimeStyle:NSDateFormatterShortStyle];
//设置NSDateFormatter的NSLocale
[df[i*4]setLocale:locales[i]];
df[i*4+1]=[[NSDateFormatter
alloc]init];
[df[i*4+1]setDateStyle:NSDateFormatterMediumStyle];
[df[i*4+1]setTimeStyle:NSDateFormatterMediumStyle];
//设置NSDateFormatter的NSLocale
[df[i*4+1]setLocale:locales[i]];
df[i*4+2]=[[NSDateFormatter
alloc]init];
[df[i*4+2]setDateStyle:NSDateFormatterLongStyle];
[df[i*4+2]setTimeStyle:NSDateFormatterLongStyle];
//设置NSDateFormatter的NSLocale
[df[i*4+2]setLocale:locales[i]];
df[i*4+3]=[[NSDateFormatter
alloc]init];
[df[i*4+3]setDateStyle:NSDateFormatterFullStyle];
[df[i*4+3]setTimeStyle:NSDateFormatterFullStyle];
//设置NSDateFormatter的NSLocale
[df[i*4+3]setLocale:locales[i]];
for (int i=0; i<2; i++) {
switch (i) {
case
0:
NSLog(@"----中国日期格式----");
break;
case
1:
NSLog(@"----美国日期格式----");
break;
}
NSLog(@"short:%@",[df[i*4]
stringFromDate:dt]);
NSLog(@"mdi:%@",[df[i*4+1]
stringFromDate:dt]);
NSLog(@"long:%@",[df[i*4+2]
stringFromDate:dt]);
NSLog(@"full:%@",[df[i*4+3]
stringFromDate:dt]);
}
NSDateFormatter *df2=[[NSDateFormatter
alloc]init];
//设置自定义的格式器模板
[df2 setDateFormat:@"公元yyyy年MM月DD日
HH时mm分"];
//执行格式化
NSLog(@"**%@",[df2
stringFromDate:dt]);
NSString *dateStr=@"2013-03-02";
NSDateFormatter *df3=[[NSDateFormatter
alloc]init];
//根据日期字符串的格式设置格式模板
[df3 setDateFormat:@"yyyy-MM-DD HH时mm分"];
//将字符串转换为NSDate对象
NSDate *date2=[df3
dateFromString:dateStr ];
NSLog(@"%@",date2);
//定时器
[NSTimer scheduledTimerWithTimeInterval:<#(NSTimeInterval)#> invocation:<#(NSInvocation *)#> repeats:];
NSTimer scheduledTimerWithTimeInterval:<#(NSTimeInterval)#> target:<#(id)#> selector:<#(SEL)#> userInfo:<#(id)#> repeats:<#(BOOL)#>
//timeInterval:指定每隔多少秒执行一次任务
//invocation或target或selector:指定重复执行的任务
//userUnfo:该参数用于指定用某个对象的特定方法作为重复至ing的任务
//repeats:控制是否需要重复执行任务。
[timer invalidate];//销毁定时器
——————————————
1.Objective-C中,与alloc语义相反的方法是dealloc还是release?与retain语义相反的方法是dealloc还是release,为什么?需要与alloc配对使用的方法是dealloc还是release,为什么?
答:alloc与dealloc语意相反,alloc是创建变量,dealloc是释放变量。
retain 对应release,retain
保留一个对象。调用之后,变量的计数加1。
2.在一个对象的方法里面:
self.name = “object”;
和
name =”object”
有什么不同吗?
答:self.name = "object"会调用对象的setName()方法,name = "object"会直接把object赋值给当前对象的name
属性。
4.什么是retain count?
答:引用计数(ref count或者retain count)。对象的内部保存一个数字,表示被引用的次数。例如,某个对象被两个指针所指向(引用)那么它的retain count为2。需要销毁对
象的时候,不直接调用dealloc,而是调用release。release会
让retain count减1,只有retain count等于0,系统才会调用dealloc真正销毁这个对象。
6.为什么很多内置类如UITableViewController的delegate属性都是assign而不是retain的?
答:会引起循环引用。
14.什么是KVC和KVO?
答:KVC(Key-Value-Coding)内部的实现:一个对象在调用setValue的时候,(1)首先根据方法名找到运行方法的时候所需要的环境参数。(2)他会从自己isa指针结合环境参数,找到具体的方法实现的接口。(3)再直接查找得来的具体的方法实现。KVO(Key-Value-Observing):当观察者为一个对象的属性进行了注册,被观察对象的isa指针被修改的时候,isa指针就会指向一个中间类,而不是真实的类。所以isa指针其实不需要指向实例对象真实的类。所以我们的程序最好不要依赖于isa指针。在调用类的方法的时候,最好要明确对象实例的类名。
13.线程与进程的区别和联系?
进程和线程都是由操作系统所体会的程序运行的基本 单元,系统利用该基本单元实现系统对应用的并发性。
程和线程的主要差别在于它们是不同的操作系统资源 管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变
量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一
些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程
强调的是功能行为
关注的是解决问题需要哪些步骤
面向对象
将功能封装进对象,强调具备功能的对象
关注的是解决问题需要哪些对象
面向对象是基于面向过程的
OC基本所有的关键字以@开头
使用sizeof()判断变量所占用的内存空间:
在64为Mac系统上,short int(2个字节)、int(4)、long int(8)、long long(8)
在iOS系统上,short int(2个字节)、int(4)、long int(4)、long long(8)
Object-c
c
后缀名.m
后缀名 .c
#import #include
可以防止头文件的重复包含
Foundation stdio
NSString ,…
自动释放池
NSLog(@“”); printf(“”);
1自动换行
2添加时间戳(项目名)
3多@
NString * 对象名称=@“字符串内容”;//定义字符串
NSLog(@“ %@ ”,对象名称);
int *p=(int *)malloc(sizeof(int));
对象在栈区分配,记录了在堆区的首地址
注释:
单行注释://
多行注释:/* */
#if 0/1 …………#endif
0被注释 1被启用
NSLog完全具备printf的功能,而printf只能打印纯C语言的变量,不能打印一些NSObject类型的对
象;NSLog(@“ ”)自带换行功能
NSLog函数输出格式
%@ 对象
%d,%i 整数
%u 无符整型
%f 浮点、双字
%X,%x 二进制数
%o 八进制数
%zu size_t
%p 指针
%e 浮点、双字(科学计算(指数))
%g 浮点、双字(
省略小数点后面无意义的零,保留小数点5位有意义的数字)
%s C字符串
%.*s Pascal字符串
%c 字符
%C unichar
%lld 64位长整数(long long)
%llu 无符64位长整数
%Lf 64位双字
%li=%ld
Cocoa对其所有的函数、常量、类型前面都会增加“NS”,前缀用于区分该函数Cocoa,而不是
其他程序包
NSString
NSDate
NSData
UIKit
Foundation
stdio
autoreleasepool自动释放池 //前缀“NS”4.0版本使用
main()函数使用了@autoreleasepool{}来包含所有的代码,位于@autoreleasepool之后的{}被称为自
动释放池,该池会自动回收这些语句所创建的对象。保证Objective-C能自动释放内存,避免引起
内存泄露。
int main() //接口
command+b编译
command+r运行
_____________________________________________________
类是多个同种类型事物的抽象;一个类可以实例化多个对象。
一个类由三部分构成:类的名称、类的属性、类的方法
对象:类类型的变量,是系统中的基本运行实体
方法的声明和实现,都必须以“+”“-”开头
+表示类方法(静态方法),直接用类名即可调用
类方法不能方位实例(成员)变量,类方法由类调用,并没有
创建存储空间来存储类中的成员变量。。格式:[类名 类方法名];
类方法的好处和适用场合:
1、不依赖于对象,执行效率更高
2、能用类方法解决的问题,尽量适用类方法
3、场合:当方法内部不需要使用到成员变量时,可以改为
类方法
-表示对象方法(动态方法),必须用对象才能调用
可以访问当前对象的成员的成员变量。。格式:[对象名 对象方法名];
在.h中声明的所有方法作用域都是public类型,不能更改
成员变量的常用的作用域有3种
1@public全局都可以访问
2@protected只能在类内部和子类中访问
3@private只能在类内部访问
@interface 类名:NSObject
//.h类的声明文件 “:”表示继承
{ //没有属性时,花括号可以省略
NSString * 属性1;
//注意“ * ”
NSInterger 属性2;
}
-(void)方法名;
@end
@implementation
类名 //.m类的实现文件
-(void)方法名
{
NSLog(@“想要输出的内容”);
}
@end
int main()
{
@autoreleasepool
{
类名 * 对象名=[类名 new];
//静态方法new创建一个对象
[对象名 方法名];
}
}
——————————————————————————————————
setter函数,对成员变量赋值
getter函数,对成员变量取值
#pragma mark age 的 setter 和 getter方法
.h
-(void)setAge:(int)newAge
andHeight:(float)newHeight //一个冒号对应一个参数
-(int)age
//get方法
.m
-(void)setAge:(int)newAge
//set合并,get方法不能合并
{
age=newAge;
height=newHeight;
}
-(int)newAge
// get
{
return age;
}
-(float)newHeight
{
return height;
}
int main()
{
[对象名 setAge:数字 setHeight:数字];
NSLog(@“%li%li”,[对象名 参数名],[对象名 参数名]);
}
{}花括号的作用是定义一个代码块
[]方括号的作用是用于访问数组元素
导入文件时,双引号“ ”和尖括号< >的区别
“ ”首先找的是自定义的一些类,之后去系统库中寻找
< >直接去系统库中寻找类的头文件
注意:导入头文件错误(.m)
——————————————————————————————————————
在.m文件里初始化
-(id/instancetype)init{
self=[super init]
if(self){
_name=@“xxx”;
_age=21;
}
return self;
}
//[super init] 的作用:面向对象的体现:先利用父类的init方法为子类实例的父类属性初始化;
self为什么要赋值[super init]:防止父类的初始化release掉self指向的空间并重新alloc一
块空间。[super init]可能失败,这时不执行if
在main函数中
[类名 * 对象名]=[[类名 alloc]init];
NSLog();
或:
.h
-(instancetype)initWithName:(NSString *)name andAge:(NSInteger)age;
get方法;
.m
-(instancetype)initWithName:(NSString*)name andAge:(NSInteger)age{
self=[super init];
if(self){
_name=name;
_age=age;
}
return self;
}
get方法;
main.m
Person *person1=[[Person alloc]init];
[person1 initWithName:@"小A"andAge:10];
NSLog(@"%@%li岁了",[person1 name],[person1 age]);
id 是一个泛型指针,用于各种对象各种指
注意:.m文件缺少get方法
——————————————————————————————————————
合成存取器
自动化@property和@synthesize
.h@property(copy,nonatomic)NSSring*
属性1;
@property(assign,nonatomic)NSInteger
属性2;
.m@synthesize
属性1;
@synthesize
属性2;
car类 属性:品牌 /Color/size/piace 方法:载人 、
#if 0 **** #endif//表示***这段代码被注释,如果if后面是1,表示被启用
——————————————————————————————————————
继承:子类拥有父类所有的属性和方法特征
派生:子类在父类的基础上又增加了新的属性和方法
方法:1,当我们发现我们封装的许多类中,有一部分功能是耦合的,可以使用继承把这些相同的功能模块
封装成一个父类。2,使用继承统一接口【父类指针可以指向子类对象】id指针可以表示任何对象
继承的优点:
1、代码复用
2、代码的扩充:子类在父类的基础上可以增加自己的实例变量和方法
什么时候使用继承:
1、创建大量相似的类
2、继承官方类(alloc init)
Xcode4.5以上的版本可以省略synthesize ’译器会自动帮你加上set get方法实现,并且默认会访问_name定义的属性,如过找不到定义的属性,会自动生成一个_name私有的成员变量,并且默认去访问
——————————————————————————————————————————
封装是面向对象的三大特征之一(继承、多态):将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问
目的:隐藏类的实现细节
让使用者只能通过事先预定的方法来访问数据,从而可以在该方法里加入控制逻辑,限制对成员变量的不合理访问
可进行数据检查,从而有利于保证对象信息的完整性
便于修改,提高代码的可维护性
为了实现良好的封装,需要从以下两个方面考虑:
将对象的成员变量和实现细节隐藏起来,不允许外部直接访问
把方法暴露出来,让方法来控制对这些成员变量进行安全的访问和操作
封装:该隐藏的隐藏,该暴露的暴露,需要通过使用访问控制符来实现
@private @package @protected @public
@public:共有访问
1类中的方法可以直接访问,该类对象可以直接访问
2子类中的方法可以直接访问,子类的对象可以直接访问方法
@protected:保护访问
1类中的方法可以直接访问,该类对象不可以直接访问
2子类中的方法可以直接访问,子类的对象不可以直接访问方法
@private:私有访问
1类中的方法可以直接访问,该类对象不可以直接访问
2子类中的方法不可以直接访问,子类的对象不可以直接访问方法
______________________________________________________________________________
工程名下搜索gar 在错误信息中含有ARC的错误,修改为手动释放
Yes自动释放内存,NO手动释放
只要含有alloc的都要进行release释放
______________________________________________________________________________
实例对象结果调用对象decription方法
-(NSString *)decription
{
return [NSString stringWithFormat:@“age=%d,name=%@”,_age,_name];
}
类对象结果调用类方法decription
{
return @“类方法description”;
}
注意:1、description方法的返回值为NSString类型;2在方法内部使用NSLog(“%@”,self);会引发死循环
————————————————————————————————————————
static关键字不能用于修饰成员变量,它只能修饰局部变量、全局变量和函数,static修饰局部变量表示就爱那个该局部变量存储到静态存储区;static修饰全局变量用于限制该全局变量只能在当前源文件中访问;static修饰函数用于限制该函数只能在当前源文件中调用
——————————————————————————————————————————
复合:一个类由两个或多个其他指针构成,就是一个复合类。
在棧区分配一块内存:动态分配内存
使用复合:复合对象保证对象指针有一个有效的指向;也就是有自持有的内存。
注意:1必须初始化 2setter和getter方法 3property synthesize
在使用中如果定义不同的类型对其使用方式:
@property(copy,nonatomic)NSString
str;字符串
@property(assign,nonatomic)NSInteger
it;整形
@property(retain,nonatomic)Mother *mom;类类型(一般在复合中使用)
return:该属性原来所引用的对象的引用计数减1,被赋值对象的引用计数加1
封装的好处:1.重用;2.不必关心具体的实现;3.面向对象三大特征之一;4具有安全性
———————————————————————————————
(“int”到“课程”的隐式转换是不允许带弧)
比较:上错下对
—————————————————————————————————————
没有返回值导致的
————————————————————————
“==”判断两个变量是否相等时,如果两个变量是基本的变量,且都是数值型
(不一定要求数据类型严格相同),则只要两个变量的值相等,就将返回
真。对于两个指针类型的变量,它们必须指向同一个对象(也就是两个指针 变量保存的内存地址相同)时,==判断才会返回真,如果判断两个没有继承
关系的指针变量时,编译器会提示警告
isEqual:方法是NSObject类提供的一个实例方法,因此,所有的指针变量都可 调用该方法来判断是否与其他指针变量相等。但这个方法判断两个对象相等
的标准与“==”符号没有区别
正确地重写isEqual:方法应该满足下列条件
自反性:对任意x,[x isEqual:x]一定返回真。
对称性:对任意x和y,如果[y isEqual:x]返回真,则[x isEqual:y]也返回值。
传递性:对任意x、y、z,如果有[x isEqual:y]返回真,[x isEqual:y]一定返
回真。
一致型:对任意x和y,如果对象中用于等价比较的关键信息没有改变,那么
无论调用[x isEqual:y]多少次,返回的结果应该保持一致,要么一直是
真,要么一直是假。
对于任何不是nil的x,[x isEqual:,nil]一定返回假
isEqual:首先判断两个对象是否类型一致,在判断具体内容是否一致,如果类型不同直接 return no。
isEqualToString:这个直接判断字符串内容,要确保比较的对象保证是字符串
“==”直接比较指向的地址
————————————————————————
总结:练习的少,过一段时间会忘记某个知识点具体怎么使用,考试的时候没有很好的去分析题意,以至于没写完,程序不细心出的小警告,觉得不重要,就没有截图保存下来
————————————————————————
多态:同一个接口,不同的实现,父类的指针指向不同的子类对象,调用相同的方法,效果不同
多态——--并列类:可以获取自己的属性和方法。对象所在类与开辟空间所对应的类同时声明了一个共同的方法或属性,那么可以对其进行调用。
继承类:只能获取包括本身在内和父类中所有的属性和方法。
使用总结:(正常)多态就是通过父类创建的对象,而对象所指向的子类的不同,而输出不同的结果。如果是并列类,那么那个类创建的对象,就会执行所在类的所有方法和属性,如果在创建空间类中也存在相同的实现,那么就会掉用创建空间的实现内容。
多态在继承中的使用:
1.父类指针可以接收子类的对象(赋值兼容规则)
2.父类的指针指向不同的子类对象,调用相同的方法,效果不同
多态父类不能索取子类中的属性与方法
继承中的子类可以任意获取父类中的属性和方法
并列类可以获取对象自己的属性和方法
对象所在类与开辟空间同时声明一个共同的方法或属性,那么可以对其调用
所创建的对象只能拿自己本身所拥有的属性和方法,无法调用对象开辟空间(那个类)中的所用的属性和方法(只能获取本身类中的方法与属性,其他类中无法获取)
________________________________________________________________’
id数据类型:可以存储任何类型的对象
可声明方法使其具有id类型的返回值
—(id)newObject:(int)type;
SEL类成员方法
在objective——C中,SEL是选择器(selector)的一个类型。选择器就是指向
方法的一个指针。
回调机制
————————————————————————————
什么是Category类别?分类又称为类别、类目、类簇、分支类
分类:在不改变原有类的基础上给这个类增加新的方法
注意:分类只能增加方法,不增加实例变量(分类只扩充方法,不能增加成员变量的定义)
1、Category能把一个类的实现分为若干不同文件中。
2、每个Cagegory是类的一部分。
3、类的不同类别可以单独编译(可以让不同开发者负责一个Category)
4、如果把一个类Category(申明和实现)放到一个.m文件中,那么该Category外界不能访问。这样实现了C++中class的private功能
5、Category实际上就是对类的扩展。
类别的作用:
1.向类中添加方法
2.类别方法的优先级高于类中方法的优先级,类和分类中如果有相同名称的方法(如果相同的话会覆盖掉原来类)
3.将相同作用的方法,放到一个类别中,这样可以降低类中的方法的数量,便于开发和维护
类别3种用法:
1、利用类别对类进行模块化设计
2、使用类别来调用私有方法
3、使用类别来实现非正式协议
类别的使用
1.基本类别无法添加属性
2.在main。m中导入分类的头文件,即可创建主类对象,创建的对象可以调用主类和分类的所有方法(不包括分类的属性)
类别Category命名规范
1、一般Category命名规范
要扩展类名+扩展变量.[hm]
比如:NSString+ReverseString.h
NSString+ReverseString.m
UIImageView+WebCache.h
UIImageView+WebCache.m
2、NSString+Reverse.h头文件
NSString+Reverse.h
#import<Foundation/Foundation.h>
@interface NSString(reverse)
-(NSString *)reverseString
@end
3、unichar c=[self characterAtIndex:--len];
NOLog(@"c is C%",c);
注意这里的c是unichar类型,这里的c是包含2个字节的国际字符,所以用C%来表示。这是OC里面特有的东西。
4、实现函数的私有化
@interface Foo(Private)
- (void) test2;
@end;
@implementation Foo
- (void) test
{
[self test2];
}
- (void) test2
{
NSLog(@"test2 is calling");
}
@end;
这个例子用Category实现了函数的私有化。
创建类别:
1、在分类中先导入主类的头文件
2、在分类的。h和。m文件中把@interface后面修改为:
主类类名(分类类名)
形式:接口 @interface 已有类(类别名)
//方法定义
@end
实现部分@implementation 已有类(类别名)
//方法实现
@end
匿名类别将属性,方法私有化
在OC中,只有类方法和实例方法,不存在私有方法,但是在。m文件中实现而不在。h文件中声明的方法称之为私有方法
扩展相当于匿名类别,语法:
@interface 已有类()
{
实例变量
}
//方法定义
……
@end
私有化后所创建的对象就无法在进行访问,从而进行代码的保护
1--在分类中.m文件中不能使用@synthesize要修改为:@dynamic否则会报错。
2—已经分过类的分类中(不包括主类),不能再次分类
四、字符串的翻转方法函数扩展
建立一个Category的项目后,
NSString+ReverseString.h代码:
#import <Foundation/Foundation.h>
@interface NSString (ReverseString)
- (id) reverseString;
@end
NSString+ReverseString.m
#import "NSString+ReverseString.h"
@implementation NSString (ReverseString)
- (id) reverseString
{
NSUInteger len = [self length];
// self
表示字符串本身
NSMutableString *retStr = [NSMutableString stringWithCapacity:len];
while (len > 0) {
unichar c = [self characterAtIndex:--len];
//
从后取一个字符 unicode
NSLog(@" c is %C", c);
NSString *s = [NSString stringWithFormat:
@"%C", c];
[retStr appendString:s];
}
return retStr;
}
@end
main.m
#import <Foundation/Foundation.h>
#import "NSString+ReverseString.h"
int main (int argc,
const char * argv[])
{
@autoreleasepool {
NSLog(@"Hello, World!");
NSString *string =
@"中国万岁hello";
NSString *retString = [string reverseString];
NSLog(@"ret string is %@", retString);
}
return 0;
}
使用NSString stringWithFormat:类方法创建的字符串对象是运行时创建出来的,它被保存在运行时内存区内(堆内存),不会防区常量池中,因此保存的地址并不相同。
协议的作用类似于接口,用于定义两个或多个类应该遵守的规范。协议不提供任何实现,体现的是规范和实现分离的设计哲学(好处是一种松耦合的设计)
正式协议的定义使用@protocol关键字
@protocol 协议名<父协议1,父协议2>{
零个到多个方法定义……
}
协议名应与类名采用相同的命名规则;
一个协议可以有多个直接父协议,但协议只能继承协议,不能继承类;
协议中定义的方法只有方法签名,没有方法实现;协议中包含的方法既可是
类方法,也可是实例方法;
遵守(实现)协议
语法:@interface 类名:父类<协议1,协议2……>
@implement 类名:父类<协议1,协议2……>
在程序中使用协议来定义变量。语法:
NSObject<协议1,协议2……>*变量;
id<协议1,协议2……>*变量;
正式协议与非正式协议的区别:
1、非正式协议通过为NSObject创建类别来实现,而正式协议则直接使用
@protocol创建
2、遵守非正式协议通过继承带特定类别的NSObject来实现;而遵守正式协议则必须实现协议中定义的所有方法
3、遵守非正式协议不要求实现协议中定义的所方法;而遵守正式协议则必须实现协议中定义的所有方法
@optional:位于该关键字之后、@requird或@end之前声明的方法是可选的
@required:位于该关键字之后、@requird或@end之前声明的方法是必需的
在协议.h文件中缺少@end
协议格式:
1、创建一个.h文件,将Foundation框架复制到该文件中,声明协议
@protocol name<NSObject>
代码(方法)区
@end
2、在对象类中导入协议文件的头文件
3、遵守协议(协议名)
4、.h导入声明的方法
5、.m实现声明的协议方法
1、在对象类中直接添加协议的方法
2、@protocol name<NSObject>
代码(方法)区
@end
3、遵守协议<协议名>
4、.h导入声明的方法
5、.m实现声明的协议方法
委托代理
委托方:
1、先导头文件(协议)
2、delegate
@property(retain,nonatomic)id<saleTo> delegate;
-(void)commond;
3、command方法声明、实现
-(void)commond{
//第1种方法
// [self.delegate performSelector:@selector(方法名)];
//第2种方法
两者任选其一
if([self.delegate respondsToSelector:@selector(方法名)])
{
[self.delegate 方法名 ];
}
}
代理方:
1、先导头文件(协议)
2、协议中的方法实现
main:
1、先导头文件(代理方,委托方)
2、委托方,代理方 都实例化一个对象
3、委托方的对象名.delegate = 代理方对象名
4、【委托方的对象名.delegate 协议中的方法】;
或者【委托方的对象名 command方法】;
双向的委托代理时,必须把协议单独拿出来
这样的警告说只导入协议,没有在。h里面遵守协议
委托代理
错误:终止应用程序由于未捕获的异常,无法识别的选择发送到实例.
原因:如上图,retain,错写成copy
构造函数:为实现某个功能,将属性传入该方法,将属性实现,传参是一种特殊方法。主要用来创建对象时初始化对象,即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中
特点:1.构造函数的命名必须和类名完全相同
2.构造函数的功能主要用于在类的对象创建时定义初始化的状态。它没有返回值,也不能用void来修饰。
3.构造函数不能被直接调用,必须通过new运算符在创建对象时才会自动调用,er一般方法是在程序执行到它的时候才会被调用。
4.当定义一个类的时候,通常情况下都会显示该类的构造函数,并在函数中指定初始化的工作
析构函数:对声明的属性,进行释放
析构函数与构造函数相反,当对象脱离其作用域时(例如对象所在的函数已调用完毕),系统自动执行析构函数。用来“清理善后”工作
使用super关键字调用父类的方法
self是一个指针,只想当前调用此方法的对象,super是一个关键字,不是对象,只是调用父类方法的一种制。
super是指向直接父类的指针,而self是指向本身的指针。self相当于JAVA中的this指针
self:1.调属性(如果调不到,使用下划线属性名)
2.调方法
_____________________________________________________
◆ 字符串
C语言中的字符串:char a[10]=“”;(字符串使用双引号)
单个字符:char a=‘A’;
OC中的字符串:
NSString *str=@“”;
区别:1、“类型修饰符” 2、@“”
最常用的方法:NSString *string = @“字符串”;(只能用来初始化不可变字符串,不能用来初始化可变字符串)
不兼容的类型的指针初始化一个NSMutableString *表达型”NSString *”
1:对象方法
- (instancetype)initWithFormat:(NSString *)format, …;//通过格式化控制初始化字符串
- (instancetype)initWithUTF8String:(const char *)bytes;//通过c字符串初始化oc字符串
2:类方法
+ (instancetype)stringWithString:(NSString *)aString;
+ (instancetype)stringWithFormat:(NSString *)format,, …;
+ (instancetype)stringWithUTF8String:(const char *)bytes;
- (NSString *)stringByAppendingString:(NSString *)aString;
错误
UTF赋值时不能加@
2:求字符串的长度
- (NSUInteger)length;//返回字符串的长度(自带的一个属性)
3:通过索引获取字符串中相应字符(字符串中成员的引用)
-
(unichar)characterAtIndex:(NSUInteger)index;//返回获取的字符
4:字符串的比较
//判断两个字符串是否相等
- (BOOL)isEqualToString:(NSString *)aString;
//比较两个字符串大小
- (NSComparisonResult)compare:(NSString *)aString;
//比较字符串时不区分大小写比较大小(输入验证码)
- (NSComparisonResult)caseInsensitiveCompare:(NSString *)aString;
5:字符串中查找子串(strstr)
- (NSRange)rangeOfString:(NSString *)aString;//在self中找aString
6:判断前后缀
- (BOOL)hasPrefix:(NSString *)aString;//前缀
- (BOOL)hasSuffix:(NSString *)aString;//后缀
7:字符串转数字
- (double)doubleValue;
- (float)floatValue;
- (int)intValue;
- (NSInteger)integerValue ;
- (long long)longLongValue ;
- (BOOL)boolValue ;
8:小写和大写之间转换
- (NSString *)uppercaseString;//小写转大写
- (NSString *)lowercaseString;//大写转小写
- (NSString *)capitalizedString;//首字母大写
9:字符串提取
- (NSString *)substringFromIndex:(NSUInteger)from;//从from位置开始一直提取到字符串的末尾
- (NSString *)substringToIndex:(NSUInteger)to;//从字符串开始提取到to位置结束
- (NSString *)substringWithRange:(NSRange)range;//提取字符串中的某个返回
与NSMutableString字符串相关操作
NSMutableString 可变字符串,字符串中的内容可以进行修改,继承于NSString
字符串追加:1、字符串;2、格式符
1:在字符串的末尾追加子符串
- (void)appendString:(NSString *)aString;
2:在字符串末尾追加格式化子符串
- (void)appendFormat:(NSString *)format, ... ;//追加的字符串是格式化字符串
3:指定索引位置插入子符串
- (void)insertString:(NSString *)aString atIndex:(NSUInteger)loc;//将在self中插入aString字符串,后面的字符串内容后移,改变了self字符串中内容
4:删除指定范围的子符串
- (void)deleteCharactersInRange:(NSRange)range;
5:修改子符串
- (void)setString:(NSString *)aString;//把整个字符串变成aString
可变字符串如果直接初始化,不能使用append追加
区别下面两种初始化上面的不可以追加,下面的可以追加
NSString *str=@"abcdefg.com";
NSMutableString *mstr1=@"###";
NSMutableString *mstr=[[NSMutableString alloc]initWithString:@"das"];
NSLog(@"1%@",mstr);
//可变字符串的拼接(尾部追加)
[mstr appendString:@"123"];
NSLog(@"2%@",mstr);
[mstr appendFormat:@"aa"];
NSLog(@"3%@",mstr);
[mstr appendString:str];
NSLog(@"4%@",mstr);
//插入字符串
[mstr insertString:mstr1 atIndex:2];
NSLog(@"5%@",mstr);
//删除
NSRange ra;
ra.length=5;
ra.location=2;
[mstr deleteCharactersInRange:ra];
NSLog(@"6%@",mstr);
//修改
[mstr setString:@"****"];
NSLog(@"7%@",mstr);
___________________________________
数组
C:
char 数组名[长度]={‘a’,’b’,’c’……};
OC:
NSArray *array
for (类型 *名字 in
所遍历的对象){
code……
})
2:c中数组和oc中数组的区别
c中的数组,数组成员一般都是基本数据类型变量,数组成员的数据类型要相同,数组没有结束的标志,数组成员的值可以直接修改
oc中的数组,数组成员一般是oc对象(也可以间接存储基本数据类型(int,float)或复合类型的数据),数组成员的数据类型可以不相同,数组末尾有结束标志nil(因为数组成员是对象指针),NSArray数组成员不能修改,NSMutableArra y数组成员可以修改
3:NSArray:不可变数组
不可变:数组一旦创建完成后,数组成员不能够被修改,数组成员不能添加和删除
注:oc中的数组成员放在小括号里(),nil是数组结束标志
1:数组的创建
常用方法:NSArray *array = @[成员列表];//只能用在不可变数组中(无需写nil)
1:对象方法//讲课时强调成员类型id,验证数组成员类型任意并且可以各不相同//将nil放到数组中间,再打印数组内容看下结果//打印的时候()里面的内容就是数组//数组成员全是中文是打印出来就是所谓的乱码,其实是网络格式
- (id)initWithObjects:(id)firstObj,
... ;(记住)
NSArray *array=[[NSArray
alloc]initWithObjects:@"ab",@"bc",@"cd",
nil];
- (id)initWithArray:(NSArray
*)array;//由于内存管理技术,导致initWithArray的数组,与原数组的地址不同
2:类方法
+ (id)arrayWithObjects:(id)firstObj,
... ;
+ (id)arrayWithArray:(NSArray *)array;
//数组的创建
void createArray(void){
//注意:数组成员初始化的时候放在[]里,打印出来的时候放在()
NSArray *array =
@[@"bei",
@"jing", @"huan",
@"huan", @"ying",
@"nin"];
#pragma mark 对象方法创建数组
//注意:nil是oc数组结束标志,如果nil在数组中间,nil后面的元素无法打印
NSArray *array1 = [[NSArray
alloc]
initWithObjects:@"bei",
@"jing", @"huan",
@"huan", @"ying",
@"nin", nil];//最常用
NSArray *array2 = [[NSArray
alloc] initWithArray:array];//用其他数组初始化当前数组
#pragma mark 类方法创建数组
NSArray *array3 = [NSArray
arrayWithObjects:@"bei",
@"jing", @"huan",
@"huan", @"ying",
@"nin", nil];//最常用
NSArray *array4 = [NSArray
arrayWithArray:array];
NSLog(@"%@", array);
NSLog(@"%@", array1);
NSLog(@"%@", array2);
NSLog(@"%@", array3);
NSLog(@"%@", array4);
}
练习1:
1:分别用对象方法和类方法分别创建一个数组array1,array2,数组成员有三个字符串@“a”,@“b”,@“c”,然后再创建一个数组array,数组成员是array1, array2
//1:分别用对象方法和类方法分别创建一个数组array1,array2,数组成员有三个字符串@“a”,@“b”,@“c”,然后再创建一个数组array,数组成员是array1,
array2
void test1(void){
//对象方法
NSArray *array1 = [[NSArray
alloc] initWithObjects:@"a",
@"b",
@"c", nil];
//类方法
NSArray *array2 = [NSArray
arrayWithObjects:@"a",
@"b",
@"c", nil];
NSArray *array = [NSArray
arrayWithObjects:array1, array2,
nil];
NSLog(@"%@", array);
}
练习2:
2:请用类方法做一个数组,数组长度为2,数组中第一个元素是一个数组,第二个元素也是一个数组,第一个元素的数组长度为2,每个成员又是一个数组,两个小数组分别为2,3,存的都是字符串,内容为A、B 和A、B、C, 第二个元素的数组长度为1,存的一个字符串A
//2:请用类方法做一个数组,数组长度为2,数组中第一个元素是一个数组,第二个元素也是一个数组,第一个元素的数组长度为2,每个成员又是一个数组,两个小数组分别为2,3,存的都是字符串,内容为A、B
和A、B、C,
第二个元素的数组长度为1,存的一个字符串A
void test2(void){
NSArray *array1_1 = [NSArray
arrayWithObjects:@"A",
@"B",
nil];
NSArray *array1_2 = [NSArray
arrayWithObjects:@"A",
@"B",
@"C", nil];
NSArray *array1 = [NSArray
arrayWithObjects:array1_1, array1_2,
nil];
NSArray *array2 = [NSArray
arrayWithObjects:@"A",
nil];
NSArray *array = [NSArray
arrayWithObjects:array1, array2,
nil];
NSLog(@"%@", array);
}
2:获取数组元素的个数
- (NSUInteger)count;//返回数组中元素个数
3:通过索引获取相应的元素//返回什么类型元素就要用什么类型对象接收//下标越界会报错
- (id)objectAtIndex:(NSUInteger)index;
//数组元素个数
void countOfArray(void){
NSArray *array = [NSArray
arrayWithObjects:@"bei",
@"jing", @"huan",
@"ying", @"nin",
nil];
NSLog(@"%lu", [array
count]);
}
//数组成员的引用
void objectInArray(void){
NSArray *array = [NSArray
arrayWithObjects:@"bei",
@"jing", @"huan",
@"ying", @"nin",
nil];
NSLog(@"%@", [array
objectAtIndex:1]);
NSLog(@"%@", array[1]);
}
1:分别用对象方法和类方法分别创建一个数组array1,array2,数组成员分别是三个字符串@“a”,@“b”,@“c”和@“e”. @“f”, @“g”,然后再创建一个数组array,数组成员是array1, array2,取出array的第一个成员,输出该成员下表为1的成员值。
//1:分别用对象方法和类方法分别创建一个数组array1,array2,数组成员分别是三个字符串@“a”,@“b”,@“c”和@“e”. @“f”, @“g”,然后再创建一个数组array,数组成员是array1,
array2,取出array的第一个成员,输出该成员下表为1的成员值。
void test3(void){
NSArray *array1 = [NSArray
arrayWithObjects:@"a",@"b",@"c",
nil];
NSArray *array2 = [NSArray
arrayWithObjects:@"e",@"f",@"g",
nil];
NSArray *array = [NSArray
arrayWithObjects:array1, array2,
nil];
NSLog(@"%@", [[array
objectAtIndex:0]
objectAtIndex:1]);
}
练习3:
循环遍历数组中每个成员的值,并输出
void test4(void){
NSArray *array = [NSArray
arrayWithObjects:@"bei",
@"jing", @"huan",
@"ying", @"nin",
nil];
#if 0
NSUInteger count = [array count];
for (int i=0; i<count; i++) {
NSLog(@"%@", [array objectAtIndex:i]);
NSLog(@"%@", array[i]);
}
#endif
#if 0
for (NSString *string
in array) {
NSLog(@"%@", string);
}
#endif
for (id temp
in array) {
NSLog(@"%@", temp);
}
}
4:数组成员的遍历(traverse)
1:for
2:快速枚举法for-in
//第一种数组成员的类型全部相同且已知(例如:类型全为NSString)
//第二种数组成员的类型不相同,且类型不已知(用id)
练习4:创建一个数组,长度为4,每个都是字符串,依次为abc, EFG, JQK, LIU
//分别使用循环变量和快速遍历方式遍历这个数组,打印数组中的每一个元素
5:通过对象地址获取在数组中的索引值
- (NSUInteger)indexOfObject:(id)anObject;
//通过成员值找对应下标
void indexOfArray(void){
NSArray *array = [NSArray
arrayWithObjects:@"bei",
@"jing", @"huan",
@"ying", @"nin",
nil];
NSLog(@"%lu", [array
indexOfObject:@"bei"]);
}
6:判断数组中是否包含某个元素
- (BOOL)containsObject:(id)anObject;
//判断数组中是否包含某个元素
void isContainObject(void){
NSArray *array = [NSArray
arrayWithObjects:@"bei",
@"jing", @"huan",
@"ying", @"nin",
nil];
BOOL bl = [array
containsObject:@"huan"];
if (bl) {
NSLog(@"包含该元素");
} else {
NSLog(@"不包含该元素");
}
}
7:获取数组的最后一个元素
- (id)lastObject;
//获取数组中最后一个元素
void lastObject(void){
NSArray *array = [NSArray
arrayWithObjects:@"bei",
@"jing", @"huan",
@"ying", @"nin",
nil];
NSLog(@"%@", [array
lastObject]);
NSLog(@"%@", [array
objectAtIndex:[array
count]-1]);
}
例子:将字符串chen$chao$ni$hao$ma变成chen chao ni hao ma
8:数组成员用指定字符串进行分割//将字符串拆成数组对象(字符串的方法,将字符串进行切割成数组,分割成的每个部分是数组成员)
- (NSArray *)componentsSeparatedByString:(NSString
*)separator;
9:把数组元素内容按照字符串separator进行拼接//将数组成员拼成字符串
- (NSString *)componentsJoinedByString:(NSString
*)separator;
//将字符串chen$chao$ni$hao$ma变成字符串chen chao ni hao ma
void separteAndJoin(void){
NSString *string =
@"chen$chao$ni$hao$ma";
//- (NSArray *)componentsSeparatedByString:(NSString *)separator;
//作用:字符串的切割,将字符串切成数组(字符串方法)
NSArray *arrayFromString = [string
componentsSeparatedByString:@“$”];//只能去除一个特殊符号
NSLog(@"%@", arrayFromString);
//- (NSString *)componentsJoinedByString:(NSString *)separator;
//作用:将数组元素拼成字符串(数组方法)
NSString *stringFromArray = [arrayFromString
componentsJoinedByString:@" "];
NSLog(@"%@", stringFromArray);
}
练习5:将字符串中的国军改成XXXX
字符串:@“今天是国庆节,我观看了中国军队演习,中国军队威武,中国军队霸气,中国军队万岁,中国军队雄起”
//练习5:将字符串中的国军改成XXXX
//字符串:@“今天是国庆节,我观看了中国军队演习,中国军队威武,中国军队霸气,中国军队万岁,中国军队雄起”
void test6(void){
NSString *string =
@"今天是国庆节,我观看了中国军队演习,中国军队威武,中国军队霸气,中国军队万岁,中国军队雄起";
// NSArray *arrayFromString = [string componentsSeparatedByString:@"国军"];
// NSString *stringFromArray = [arrayFromString componentsJoinedByString:@"XXXX"];
NSLog(@"%@", [[string
componentsSeparatedByString:@"国军"]
componentsJoinedByString:@"XXXX"]);
}
例子:将chen$chao#ni@hao&ma变成chen
chao ni hao ma
10:按照字符集合分割
- (NSArray *)componentsSeparatedByCharactersInSet:(NSCharacterSet
*)separator
//例子:将chen$chao#ni@hao&ma变成chen chao ni hao ma
void charaterAndJoin(void){
NSString *string =
@"chen$chao#ni@hao&ma";
//- (NSArray *)componentsSeparatedByCharactersInSet:(NSCharacterSet *)separator NS_AVAILABLE(10_5, 2_0);
//作用:按照字符集进行切割
NSArray *arrayFromString = [string
componentsSeparatedByCharactersInSet:[NSCharacterSet
characterSetWithCharactersInString:@"$#@&"]];
NSLog(@"%@", arrayFromString);
NSString *stringFromArray = [arrayFromString
componentsJoinedByString:@" "];
NSLog(@"%@", stringFromArray);
}
练习6:将字符串@“bei$jing%huan*ying nin”字符串变成
bei -jing-huan-ying-nin
//练习6:将字符串@“bei$jing%huan*ying nin”字符串变成
//bei-jing-huan-ying-nin
void test7(void){
NSString *string =
@"bei$jing%huan*ying nin";
NSLog(@"%@", [[string
componentsSeparatedByCharactersInSet:[NSCharacterSet
characterSetWithCharactersInString:@"$%* "]]componentsJoinedByString:@"-"]);
}
4:NSMutableArray:可变数组,继承自NSArray
可变数组:数组创建后,数组成员仍然可以修改,添加和删除
1:初始化可变数组
NSMutableArray *mutable = [[NSMutableArray
alloc] initWithCapacity:0];
NSMutableArray *mutable1 = [NSMutableArray
arrayWithCapacity:0];
1:增加元素
1:在数组末尾追加(插入)元素
- (void)addObject:(id)anObject;
2:在数组末尾追加(插入)一个数组
- (void)addObjectsFromArray:(NSArray
*)otherArray;
3:指定索引位置处插入元素
- (void)insertObject:(id)anObject
atIndex:(NSUInteger)index;
//在可变数组中增加元素
void addObjectInMutableArray(void){
NSArray *array = [NSArray
arrayWithObjects:@"huan",
@"ying",
@"nin", nil];
NSMutableArray *mutableArray = [NSMutableArray
arrayWithCapacity:0];//创建空数组
//- (void)addObject:(id)anObject;
//作用:在数组末尾添加元素
[mutableArray addObject:@"bei"];
[mutableArray addObject:@"jing"];
[mutableArray addObject:@"huan"];
[mutableArray addObject:@"ying"];
[mutableArray addObject:@"nin"];
NSLog(@"%@", mutableArray);
//- (void)addObjectsFromArray:(NSArray *)otherArray;
//作用:数组末尾添加一个数组
[mutableArray addObjectsFromArray:array];
NSLog(@"%@", mutableArray);
[mutableArray insertObject:@"hen"
atIndex:2];
[mutableArray insertObject:@"hen"
atIndex:6];
NSLog(@"%@", mutableArray);
}
2:删除元素
1:删除最后一个元素
- (void)removeLastObject;
2:删除指定索引的元素
- (void)removeObjectAtIndex:(NSUInteger)index;
3:删除指定元素//有多少删除多少
- (void)removeObject:(id)anObject;
4:在一定范围内删除指定元素
- (void)removeObject:(id)anObject
inRange:(NSRange)range;
5:格局一个数组删除指定的元素
- (void)removeObjectsInArray:(NSArray
*)otherArray;
6:删除所有元素
- (void)removeAllObjects;
//在数组中删除元素
void removeObject(void){
NSMutableArray *mutableArray = [NSMutableArray
arrayWithCapacity:0];
[mutableArray addObject:@"bei"];
[mutableArray addObject:@"jing"];
[mutableArray addObject:@"huan"];
[mutableArray addObject:@"ying"];
[mutableArray addObject:@"nin"];
[mutableArray addObject:@"jing"];
#if 0
//- (void)removeObject:(id)anObject;
//作用:删除指定元素
[mutableArray removeObject:@"jing"];
#endif
#if 0
//- (void)removeObjectAtIndex:(NSUInteger)index;
//作用:删除指定下标的元素
[mutableArray removeObjectAtIndex:1];
#endif
#if 0
//- (void)removeObjectsInRange:(NSRange)range;
//作用:
删除指定范围内的元素
NSRange range = {0,
2};//大括号
[mutableArray removeObjectsInRange:range];
#endif
#if 0
NSRange range = {0,
2};
//- (void)removeObject:(id)anObject inRange:(NSRange)range;
//作用:删除指定范围内的某个元素
[mutableArray removeObject:@"jing" inRange:range];
#endif
[mutableArray removeAllObjects];
NSLog(@"%@", mutableArray);
}
3:替换指定索引的元素
- (void)replaceObjectAtIndex:(NSUInteger)index
withObject:(id)anObject;
//数组元素的替换
void replaceObject(void){
NSMutableArray *mutableArray = [NSMutableArray
arrayWithCapacity:0];
[mutableArray addObject:@"bei"];
[mutableArray addObject:@"jing"];
[mutableArray addObject:@"huan"];
[mutableArray addObject:@"ying"];
[mutableArray addObject:@"nin"];
[mutableArray replaceObjectAtIndex:0
withObject:@"nan"];
NSLog(@"%@", mutableArray);
}
4:交换数组元素
- (void)exchangeObjectAtIndex:(NSUInteger)idx1
withObjectAtIndex:(NSUInteger)idx2;
//数组成员的交换
void exchangeObject(void){
NSMutableArray *mutableArray = [NSMutableArray
arrayWithCapacity:0];
[mutableArray addObject:@"bei"];
[mutableArray addObject:@"jing"];
[mutableArray addObject:@"huan"];
[mutableArray addObject:@"ying"];
[mutableArray addObject:@"nin"];
[mutableArray exchangeObjectAtIndex:0
withObjectAtIndex:2];
NSLog(@"%@", mutableArray);
}
练习:创建一个数组,数组成员是5个字符串@“bei”,@“jing”,@“huan”,@“huan”,@“ying”,@“nin”,用冒泡法对数组成员进行排序
5:排序:根据排序准则排序
- (void)sortUsingSelector:(SEL)comparator;
//创建一个数组,数组成员是5个字符串@“bei”,@“jing”,@“huan”,@“huan”,@“ying”,@“nin”,用冒泡法对数组成员进行排序
void test9(void){
#if 0
NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:0];
[mutableArray addObject:@"bei"];
[mutableArray addObject:@"jing"];
[mutableArray addObject:@"huan"];
[mutableArray addObject:@"ying"];
[mutableArray addObject:@"nin"];
NSUInteger count = [mutableArray count];
for (int j=0;j<count; j++) {//冒泡执行的次数
for (int i=0; i<count-1; i++) {//冒泡
if ([[mutableArray objectAtIndex:i] compare:[mutableArray objectAtIndex:i+1]] == NSOrderedDescending) {//相邻成员比较
[mutableArray exchangeObjectAtIndex:i withObjectAtIndex:i+1];//交换
}
}
}
NSLog(@"%@", mutableArray);
#endif
NSArray *array = [NSArray
arrayWithObjects:@"bei",
@"jing", @"huan",
@"ying", @"nin",
nil];
//注意:SEL----->@selector(方法名)
NSArray *arraySort = [array
sortedArrayUsingSelector:@selector(compare:)];
NSLog(@"%@", arraySort);
}
6:修改数组
- (void)setArray:(NSArray *)otherArray;
__________________________________
删除字符串里的符号
或
删除数字
__________________________________________________________________________
字典
key—拼音、部首
value—值(汉字)
oc中的字典:类型NSDictionary,具有键(key)和值(value),键就相当于索引,键值是唯一的,值就相当于内容,一般情况下我们可以通过键(key)找到值(value)
字典的使用:字典类型主要用于plist文件
2:字典的元素
字典的元素是键值对,所以字典的元素都是成对出现的,一个元素就是一对(有key和对应的value)
键和值都是对象类型,键和值的类型可以不同
键值对:(必须成对出现,key不可以重复)
在oc字典中,不能出现相同的key,但是可以出现相同的value,保证key的唯一性,这样就能够通过key唯一确定一个value
4:如何查找值
一般情况下,通过key找value,特殊情况下直接找value
5:NSDictionary:不可变字典
不可变字典:字典对象一旦创建完成后,字典成员不能够被修改,增加和删除
1:字典的创建//输出字典成员的时候发现字典中成员是无序的并且字典输出时内容放在{}中
//key在前value在后注意key与value中间冒号“:”隔开,结束不用nil
NSDictionary *dictionary =
@{@"key1":
@"value1",
@"key2":
@"value2"};
1:对象方法//value在前key在后
- (id)initWithObjectsAndKeys:(id)firstObject,
…;(记住)
- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray
*)keys;
2:类方法
+ (id)dictionaryWithObjectsAndKeys:(id)firstObject,
...;
+ (id)dictionaryWithObjects:(NSArray
*)objects forKeys:(NSArray *)keys;
//不可变字典的创建
void createDictionary(void){
// NSString *string = @"chen chao";
// NSArray *array = @[@"bei", @"jing"];
//字典中的元素放在大括号里的
NSDictionary *dictionary =
@{@"key1":@"value1",
@"key2":@"value2"};//比较常用
#pragma mark 对象方法创建字典
NSDictionary *dictionary1 = [[NSDictionary
alloc] initWithObjectsAndKeys:@"value1",
@"key1",
@"value2",
@"key2", nil];//最常用
NSDictionary *dictionary2 = [[NSDictionary
alloc] initWithDictionary:dictionary];//用其他字典来初始化当前字典对象
#pragma mark 类方法创建字典
NSDictionary *dictionary3 = [NSDictionary
dictionaryWithObjectsAndKeys:@"value1",
@"key1",
@"value2",
@"key2", nil];
NSDictionary *dictionary4 = [NSDictionary
dictionaryWithDictionary:dictionary];
NSLog(@"%@", dictionary);
NSLog(@"%@", dictionary1);
NSLog(@"%@", dictionary2);
NSLog(@"%@", dictionary3);
NSLog(@"%@", dictionary4);
}
2:获取键值对的个数
- (NSUInteger)count;
3:根据键key获取相应值value
- (id)objectForKey:(id)aKey;
4:获取字典中所有的key
- (NSArray *)allKeys;
练习1:输出字典中所有的value值
//练习1:输出字典中所有的value值
void test1(void){
NSDictionary *dictionary = [NSDictionary
dictionaryWithObjectsAndKeys:@"value1",
@"key1",
@"value2",
@"key2", nil];
NSArray *arrayKey = [dictionary
allKeys];//获取字典中所有的key值
for (NSString *key
in arrayKey) {//取出每个key
NSLog(@"%@", [dictionary
objectForKey:key]);//根据key找到对应的value
}
}
5:获取与某个值value对应的所有键key
- (NSArray *)allKeysForObject:(id)anObject;
6:获取字典中的所有值
- (NSArray *)allValues;
//根据value找key
void fromValueToFindKey(void){
NSDictionary *dictionary = [NSDictionary
dictionaryWithObjectsAndKeys:@"value1",
@"key1",
@"value1",
@"key2", nil];
//- (NSArray *)allKeysForObject:(id)anObject;
//作用:根据value找到所有的key
NSArray *array = [dictionary
allKeysForObject:@"value1"];
NSLog(@"%@", array);
}
//获取数组中所有的value
void allValue(void){
NSDictionary *dictionary = [NSDictionary
dictionaryWithObjectsAndKeys:@"value1",
@"key1",
@"value2",
@"key2", nil];
NSLog(@"%@", [dictionary
allValues]);
}
练习2:创建一个字典,字典中有四个键值(key-value)对,分别是title=nike, price=10,info=good shoes, pic=shoes picture,输出键值对的个数,输出字典中所有的key和value,通过title找出对应的value值并输出
//练习2:创建一个字典,字典中有四个键值(key-value)对,分别是title=nike, price=10, info=good shoes, pic=shoes picture,输出键值对的个数,输出字典中所有的key和value,通过title找出对应的value值并输出
void test2(void){
NSDictionary *dictionary = [NSDictionary
dictionaryWithObjectsAndKeys:@"nike",
@"title", @"10",
@"price", @"good shoes",
@"info", @"shoes picture",
@"pic", nil];
NSLog(@"%lu", [dictionary
count]);
NSLog(@"%@", [dictionary
allKeys]);
NSLog(@"%@", [dictionary
allValues]);
NSLog(@"%@", [dictionary
objectForKey:@"title"]);
}
6:NSMutableDictionary:可变字典
可变字典:字典对象一旦创建完成后,字典成员仍然能够被修改,增加和删除
可变字典初始化
NSMutableDictionary *mutableDictionary1 = [[NSMutableDictionary
alloc]
initWithCapacity:0];
NSMutableDictionary *mutableDictionary2 = [NSMutableDictionary
dictionaryWithCapacity:0];
1:增加
1:在字典末尾增加一个键值对
- (void)setObject:(id)anObject
forKey:(id <NSCopying>)aKey;
2:在字典末尾增加一个字典
- (void)addEntriesFromDictionary:(NSDictionary
*)otherDictionary;
//给字典添加元素
void addObjectAndKey(void){
NSDictionary *dictionary = [NSDictionary
dictionaryWithObjectsAndKeys:@"value3",@"key3",
nil];
NSMutableDictionary *mutableDictionary = [NSMutableDictionary
dictionaryWithCapacity:0];
//string: stringByAppendingString
//mutableString: appendString
//mutableArray:addObject
//- (void)setObject:(id)anObject forKey:(id <NSCopying>)aKey;
//作用:在字典末尾增加元素
[mutableDictionary setObject:@"value1"
forKey:@"key1"];
[mutableDictionary setObject:@"value2"
forKey:@"key2"];
NSLog(@"%@", mutableDictionary);
//- (void)addEntriesFromDictionary:(NSDictionary *)otherDictionary;
//作用:在可变字典末尾添加一个字典
[mutableDictionary addEntriesFromDictionary:dictionary];
NSLog(@"%@", mutableDictionary);
}
2:删除
1:根据键key删除键值对
- (void)removeObjectForKey:(id)aKey;
2:删除所有键值对
- (void)removeAllObjects;
//删除字典中的元素
void removeObjectAndKey(void){
NSMutableDictionary *mutableDictionary = [NSMutableDictionary
dictionaryWithCapacity:0];
[mutableDictionary setObject:@"value1"
forKey:@"key1"];
[mutableDictionary setObject:@"value2"
forKey:@"key2"];
[mutableDictionary setObject:@"value3"
forKey:@"key3"];
//- (void)removeObjectForKey:(id)aKey;
//作用:删除字典中的某个键值对
[mutableDictionary removeObjectForKey:@"key1"];
NSLog(@"%@", mutableDictionary);
//- (void)removeAllObjects;
//作用:删除字典中所有的键值对
[mutableDictionary removeAllObjects];
NSLog(@"%@", mutableDictionary);
}
4:修改整个字典
//修改整个字典
- (void)setDictionary:(NSDictionary *)otherDictionary;
//修改键值对
//key不存在表示增加 key存在表示修改key对应的值
- (void)setObject:(id)anObject forKey:(id
<NSCopying>)aKey;
//修改字典
void setMutableDictionary(void){
NSMutableDictionary *mutableDictionary = [NSMutableDictionary
dictionaryWithCapacity:0];
[mutableDictionary setObject:@"value1"
forKey:@"key1"];
[mutableDictionary setObject:@"value2"
forKey:@"key2"];
[mutableDictionary setObject:@"value3"
forKey:@"key3"];
NSLog(@"%@", mutableDictionary);
[mutableDictionary setObject:@"value4"
forKey:@"key1"];
NSLog(@"%@", mutableDictionary);
NSDictionary *dictionary = [NSDictionary
dictionaryWithObjectsAndKeys:@"value4",
@"key4",
nil];
[mutableDictionary setDictionary:dictionary];
NSLog(@"%@", mutableDictionary);
}
_____________________________________________________
单例
共享资源,优化内存
——————————————————————————————————————————————
析构函数
-(void)dealloc
{
[_name release];
或_name=nil;
[super dealloc];
}
@end
——————————————————————————————————————————
#pragma mark - ** 快速找到文件
电脑休眠 格式:
【NSThread sleepForTimeInterval:1】;//暂停1秒
________________________________________________________
数据存储
1:为什么要使用数据持久化
思考:我们使用的qq登录信息,播放器里播放记录,浏览器的收藏,为什么是在每次启动应用程序的时候,这些信息都会存在?正常情况下应用程序结束时,程序中所使用的数据都会被系统自动释放,如果想把程序运行过程中或程序运行结束后的某些信息持久化的保存起来,这时候就用到的数据持久化
2:什么是数据持久化
数据持久化:将数据模型转换成存储模型(将内存中的数据保存到磁盘中)
3:数据持久化的优点
将数据持久的保存起来,不会丢失
4:数据持久化的方式
1:文件
2:Plist文件: 也称之为属性化列表文件,plist文件是一个轻量级的数据库,用于存放一些比较小的数据,文件是xml格式的,只能保存NSArray和NSDictionary
3:归档和反归档:归档是将内存中的任意类型对象写入文件保存到磁盘中,反归档是将磁盘中的文件还原成原来的变量
4:NSUserDefault:持久化标签(UI)
5:数据库:网络 FMDB:世纪封装sqlite数据库 coredata:在数据库的基础上增加了面向对象的语法 第三方的库
PList
1:什么是plist文件
plist全称:property List 属性列表文件,plist是一个xml格式文件,后缀为.plist,只能持久化NSArray和NADictionary类型对象
2:plist文件的作用
作用:plist是做数据持久化的专业文件,.plist一般情况下用于存储用户密码、临时信息、简介这样的简单
3:Plist文件特点(先将Xcode创建plist文件,再通过创建好的plist文件介绍plist文件特点)
Plist文件特点:
1:Plist文件的根路径只能是数组和字典(Plist文件只能持久化数组和字典)
2:Plist文件的子路径只能是NSString NSNumber NSDate NSData NSArray NSDictionary类的对象内容不能保存其他类型数据
4:Xcode创建plist文件
Plist文件内容的格式是xml语法格式
创建步骤
1.点击File--》New File 弹出一对话框
2.iOS程序选中iOS栏中的Resource/Mac程序选中OS X 栏中的resource
3.点击Resource中的Property List 创建plist文件
4.点击文件中的'+'可以添加数据
5:代码创建和读取plist文件
如果想把NSString NSNumber NSDate NSData NSArray NSDictionary类的对象写入文件中一般用plist文件,但是因为plist文件根路径只能是NSArray和NSDoctionary所以只能持久化NSArray和NSDoctionary对象,这时候就需要将数据保存再数组或字典中然后调用数组和字典的相关方法把数组和字典写入到plist文件中
//将数组和字典写入plist文件的方法
//path:plist文件的路径
//useAuxiliaryFile:是否具有原子性
- (BOOL)writeToFile:(NSString
*)path atomically:(BOOL)useAuxiliaryFile;
//将plist文件读取到数组和字典中
//将plist文件读取到数组中(类方法)
+(id)arrayWithContentsOfFile:(NSString
*)path;
//将plist文件读取到字典中(类方法)
+(id)dictionaryWithContentsOfFile:(NSString *)path
//将数组写入到plist文件中
例子1:创建一个数组,数组成员是NSString类型的对象@“bei”,@“jing”,@“huan”,@“ying”,@“nin”
把该数组持久化到一个plist文件中,并读取plist文件中内容
/*
//将数组写入到plist文件中
例子1:创建一个数组,数组成员是NSString类型的对象@“bei”,@“jing”,@“huan”,@“ying”,@“nin”
把该数组持久化到一个plist文件中,并读取plist文件中内容
*/
void test1(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";
NSArray *array = [NSArray
arrayWithObjects:@"bei",
@"jing", @"huan",
@"ying", @"nin",
nil];
//- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;
//作用:将数组写入plist文件
//path:plist文件路径
//useAuxiliaryFile:是否具有原子性
[array writeToFile:[pathDesktop
stringByAppendingString:@"/arrar1.plist"]
atomically:YES];
NSArray *arrayFromPlist = [NSArray
arrayWithContentsOfFile:[pathDesktop stringByAppendingString:@"/arrar1.plist"]];
NSLog(@"%@", arrayFromPlist);
}
例子2:创建一个数组,数组成员是两个字典对象dictionary1和dictionary2,
dictionary1中有:
@“chen chao”,@“name”
@“18”,@“age”
@“Good Teacher”,@“info”三个键值对(前面是value后面是key)
dictionary2中有:
@“liu de hua”,@“name”
@“56”,@“age”
@“actor”,@“info”三个键值对
把该数组持久化到一个plist文件中,并读取plist文件中内容
void test2(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";
NSDictionary *dictionary1 = [NSDictionary
dictionaryWithObjectsAndKeys:
@"chen chao",
@"name",
@"18",
@"age",
@"Good teacher",
@"info",nil];
NSDictionary *dictionary2 = [NSDictionary
dictionaryWithObjectsAndKeys:
@"liu de hua",
@"name",
@"56",
@"age",
@"actor",
@"info", nil];
NSArray *array = [NSArray
arrayWithObjects:dictionary1, dictionary2,
nil];
[array writeToFile:[pathDesktop
stringByAppendingString:@"/array2.plist"]
atomically:YES];
NSArray *arrayFromPlist = [NSArray
arrayWithContentsOfFile:[pathDesktop stringByAppendingString:@"/array2.plist"]];
NSLog(@"%@", arrayFromPlist);
}
//将字典写入到list文件中
例子3:创建一个字典对象,字典对象中有
@“chen chao”,@“name”
@“18”,@“age”
@“Good Teacher”,@“info”三个键值对
将该字典写入到list文件中,并读取plist文件中内容
void test3(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";
NSDictionary *dictionary = [NSDictionary
dictionaryWithObjectsAndKeys:
@"chen chao",
@"name",
@"18",
@"age",
@"Good teacher",
@"info", nil];
[dictionary writeToFile:[pathDesktop
stringByAppendingString:@"/dictionary1.plist"]
atomically:YES];
NSDictionary *dictionaryFromPlist = [NSDictionary
dictionaryWithContentsOfFile:[pathDesktop
stringByAppendingString:@"/dictionary1.plist"]];
NSLog(@"%@", dictionaryFromPlist);
}
例子4:创建一个字典,字典中有
array1, @“key1”
array2, @“key2”
array3, @“key3”
array4, @“key4”四个键值对
array1数组成员有:@“ni”, @“hao”
array2数组成员有:@“bei”, @“jing”
array3数组成员有:@“huan”
array4数组成员有:@“ying”, @“nin”,@“hao”,@“ma”
将该字典写入到list文件中,并读取plist文件中内容
void test4(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";
NSArray *array1 = [NSArray
arrayWithObjects:@"ni",
@"hao",
nil];
NSArray *array2 = [NSArray
arrayWithObjects:@"bei",
@"jing",
nil];
NSArray *array3 = [NSArray
arrayWithObjects:@"huan",
nil];
NSArray *array4 = [NSArray
arrayWithObjects:@"ying",
@"nin",
@"hao", @"ma",
nil];
NSDictionary *dictionary = [NSDictionary
dictionaryWithObjectsAndKeys:
array1, @"key1",
array2, @"key2",
array3, @"key3",
array4, @"key4",nil];
[dictionary writeToFile:[pathDesktop
stringByAppendingString:@"/dictionary2.plist"]
atomically:YES];
NSDictionary *dictionaryFromPlist = [NSDictionary
dictionaryWithContentsOfFile:[pathDesktop
stringByAppendingString:@"/dictionary2.plist"]];
NSLog(@"%@", dictionaryFromPlist);
}
练习:创建一个字典,字典中有三个元素
@“value1”,@“key1”
@“value2”,@“key2”
array, @“key3”
array是一个数组,数组中有两个字典对象dict1和dict2
dict1和dict2中有
@“value1”,@“key1”
@“value2”,@“key2”
两个键值对
将该字典写入plist文件中并读取
void test5(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";
NSDictionary *dict1 = [NSDictionary
dictionaryWithObjectsAndKeys:
@"value1",
@"key1",
@"value2",
@"key2",nil];
NSDictionary *dict2 = [NSDictionary
dictionaryWithObjectsAndKeys:
@"value1",
@"key1",
@"value2",
@"key2",nil];
NSArray *array = [NSArray
arrayWithObjects:dict1, dict2,
nil];
NSDictionary *dictionary = [NSDictionary
dictionaryWithObjectsAndKeys:
@"value1",
@"key1",
@"value2",
@"key2",
array, @"key3",nil];
[dictionary writeToFile:[pathDesktop
stringByAppendingString:@"/dict.plist"]
atomically:YES];
NSDictionary *dictionaryFromPlist = [NSDictionary
dictionaryWithContentsOfFile:[pathDesktop
stringByAppendingString:@"/dict.plist"]];
NSLog(@"%@", dictionaryFromPlist);
}
归档和反归档
1:什么是归档和反归档
归档:归档就是通过某种格式把内存中的某个对象保存到本地文件中,以便以后再从该文件中读回该对象
反归档:把归档的对象文件读成原来的内存中的对象
2:系统类对象的归档和反归档
系统类归档
//NSKeyedArchiver类的方法
+ (BOOL)archiveRootObject:(id)rootObject toFile:(NSString *)path;
系统类反归档
//NSKeyedUnarchiver类的方法
+ (id)unarchiveObjectWithFile:(NSString
*)path;
1:NSString的归档和反归档
例题:创建一个NSString类对象值为@“bei jing huan ying nin”,将该对象进行归档和反归档
//例题:创建一个NSString类对象值为@“bei jing huan ying nin”,将该对象进行归档和反归档
void test1(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";
NSString *string =
@"1439 best NB";
//+ (BOOL)archiveRootObject:(id)rootObject toFile:(NSString *)path;
//作用:对oc对象进行归档操作
[NSKeyedArchiver
archiveRootObject:string toFile:[pathDesktop
stringByAppendingString:@"/归档文件string"]];
//+ (id)unarchiveObjectWithFile:(NSString *)path;
//作用:对归档文件反归档成oc对象
NSString *stringFromArchiver = [NSKeyedUnarchiver
unarchiveObjectWithFile:[pathDesktop stringByAppendingString:@"/归档文件string"]];
NSLog(@"%@", stringFromArchiver);
}
2:NSArray的归档和反归档
例题:创建一个NSArray类对象值为@“bei”,@“jing”,@“huan”,@“ying”,@“nin”,将该对象进行归档和反归档
//例题:创建一个NSArray类对象值为@“bei”,@“jing”,@“huan”,@“ying”,@“nin”,将该对象进行归档和反归档
void test2(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";
NSArray *array = [NSArray
arrayWithObjects:@"1439",
@"have", @"a",
@"best", @"teacher",
nil];
[NSKeyedArchiver
archiveRootObject:array toFile:[pathDesktop
stringByAppendingString:@"/归档文件array"]];
NSArray *arrayFromArchiver = [NSKeyedUnarchiver
unarchiveObjectWithFile:[pathDesktop stringByAppendingString:@"/归档文件array"]];
NSLog(@"%@", arrayFromArchiver);
}
3:NSDictionary的归档和反归档
例题:创建一个NSDictionary类对象值为
@“value1”, @“key1”
@“value2”, @“key2”
@“value3”, @“key3”三个键值对,将该对象进行归档和反归档
3:自定义类对象的归档和反归档
思考:对于系统类NSString,NSArray, NSDictionary类对象可以直接进行归档和反归档操作,是不是说所有的oc类对象都能进行归档和反归档操作?
不是,只有遵守了<NSCoding>协议的类的对象才能进行归档和反归档操作
如果自定义的类对象要进行归档那么这个对象的属性所属的类也必须要遵守归档协议NSCoding
必须实现以下两个方法:
//归档的时候调用的方法
- (void)encodeWithCoder:(NSCoder *)aCoder;
//解归档的时候要调用的函数
- (id)initWithCoder:(NSCoder *)aDecoder;
例子:创建一个Student类,类中有_age和_name两个实例变量,堆Student类对象进行归档和反归档操作
Student类
Student.h
//对于一个自定义的类想要进行归档和反归档操作必须遵守NSCoding协议
//遵守NSCoding协议
#import <Foundation/Foundation.h>
//.h文件类的声明后面加上<协议名>,表示该类遵守这个协议
@interface Student :
NSObject <NSCoding>
@property (assign,
nonatomic)int age;
@property (copy,
nonatomic)NSString *name;
//协议中的内容
- (void)encodeWithCoder:(NSCoder *)aCoder;//归档操作的时候自动被调用
- (id)initWithCoder:(NSCoder *)aDecoder;//反归档的时候自动被调用
@end
Student.m
//.m实现协议中的方法
#import "Student.h"
@implementation Student
//归档的时候调用
- (void)encodeWithCoder:(NSCoder *)aCoder{
//- (void)encodeInt:(int)intv forKey:(NSString *)key;
//作用:归档int类型的数据
//key:归档的格式,归档格式任意但是以什么格式归档就需要以什么格式反归档
[aCoder encodeInt:self.age
forKey:@"age"];
//- (void)encodeObject:(id)objv forKey:(NSString *)key;
//作用:归档oc对象
[aCoder encodeObject:self.name
forKey:@"name"];
}
- (id)initWithCoder:(NSCoder *)aDecoder{
//- (int)decodeIntForKey:(NSString *)key;
//作用:反归档int类型数据
self.age = [aDecoder
decodeIntForKey:@"age"];
self.name = [aDecoder
decodeObjectForKey:@"name"];
return
self;
}
@end
main.m
#import <Foundation/Foundation.h>
#import "Student.h"
int main(int argc,
const char * argv[])
{
@autoreleasepool {
NSString *pathDesktop =
@"/Users/mac/Desktop";
Student *std = [[Student
alloc] init];
std.age =
10;
std.name =
@"xiao xin";
[NSKeyedArchiver
archiveRootObject:std toFile:[pathDesktop
stringByAppendingString:@"/归档文件student"]];
Student *stdFromArchiver = [NSKeyedUnarchiver
unarchiveObjectWithFile:[pathDesktop stringByAppendingString:@"/归档文件student"]];
NSLog(@"age is %d name is %@", stdFromArchiver.age, stdFromArchiver.name);
}
return 0;
}
练习:创建一个Person类,累中有_age和_name两个实例变量,实现Person类对象的归档和反归档
JSON
1:什么是json
json时一种轻量级的数据格式,用于数据交互
服务器返回给客户端的数据,一般都是JSON格式或者XML格式(文件下载除外)
2:json的作用
json可以将javaScript对象中表示的一组数据转换成字符串,然后就可以在函数之间轻松的传递这个字符串,或者在异步应用程序中将字符串从Web客户机传递给服务端程序,这个字符串看起来有点儿古怪,但是JavaScript很容易解释它,而且JSON可以表示比“名称/值对”更复杂的结构。例如,可以表示数组和复杂对象,而不仅时键和值的简单列表。
3:json中的基本语法
名称/值对包括字段名称(在双引号中),后面写一个冒号,然后是值。
如:“firstName”:“Tom”
4:json的值
JSON的值可以是:
1:数字(整数或浮点数)
2:字符串(双引号中)
3:逻辑值(true或false)
4:数组([]中)
5:对象({}中)
JSON – OC
转换对照表
5:JSON的结构
JSON最外曾通常有数组和字典两种结构,通过这两种结构可以表示各种复杂的结构
1:数组:数组在json中是中括号‘[]’括起来的内容,数据结构为["java","javascript","vb",…],类似于OC中的数组
2:对象:对象在json中表示为“{}”括起来的内容,数据结构为 {key:value,key:value,…}的键值对的结构,类似于oc中的字典结构
json的结构也决定了json最终只能转换成数组或字典类型的对象
@{key : value}
例如:
{
"count" : 30,
"totalcount" : "51708",
"users" : [
{
"credit" : "803",
"experience" : "680",
"friendnum" : "19",
"groupid" : "6",
"headimage" : "/my/headimage.php?uid=50519",
"lastactivity" : "1402365234",
"realname" : "曉樂",
"uid" : "50519",
"username" : "魚曉樂",
"viewnum" : "210"
},
{
"credit" : "111",
"experience" : "736",
"friendnum" : "25",
"groupid" : "6",
"headimage" : "/my/headimage.php?uid=50972",
"lastactivity" : 0,
"realname" : "啊啊啊",
"uid" : "50972",
"username" : "小爪冰凉",
"viewnum" : "86"
},
]
}
分析:最外层大括号括起来说明json是字典,字典中有三个键值对,"count”对应的value是NSNumber,"totalcount" 对应的value是NSString,"users" 对应的value是一个数组,并且该数组成员是两个字典
6:JSON解析
JSON解析方案
1.在iOS中,JSON的常见解析方案有4种
(1)第三方框架:JSONKit、SBJson、TouchJSON(性能从左到右,越差)
(2)苹果原生(自带):NSJSONSerialization(性能最好)
json文件解析(analysis)
本地json解析步骤:
1:首先调用NSString的
+ (id)stringWithContentsOfFile:(NSString
*)path encoding:(NSStringEncoding)enc error:(NSError **)error;
方法将文件读成字符串
2:然后调用NSString的
- (NSData *)dataUsingEncoding:(NSStringEncoding)encoding;
把字符串转换成NSData二进制数据
3:调用系统类NSJSONSerialization的
+ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt
error:(NSError **)error;
方法进行解析,最后解析为NSArray或者NSDictionary
例子:对本地jsonUserList.txt文件进行解析
//json文件的解析
void JsonAnalysis1(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";
//1:读取json文件内容保存在string
NSString *string = [NSString
stringWithContentsOfFile:[pathDesktop stringByAppendingString:@"/json/jsonUserList.txt"]
encoding:NSUTF8StringEncoding
error:nil];
//2:把string转换成data
NSData *dataFromString = [string
dataUsingEncoding:NSUTF8StringEncoding];
//3:将data进行json解析
NSDictionary *dictionary = [NSJSONSerialization
JSONObjectWithData:dataFromString options:NSJSONReadingMutableContainers
error:nil];
NSLog(@"%@", dictionary);
}
练习:对本地json.txt文件进行解析
void JsonAnalysis2(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";
NSString *string = [NSString
stringWithContentsOfFile:[pathDesktop stringByAppendingString:@"/json/json.txt"]
encoding:NSUTF8StringEncoding
error:nil];
NSData *dataFromString = [string
dataUsingEncoding:NSUTF8StringEncoding];
NSArray *array = [NSJSONSerialization
JSONObjectWithData:dataFromString options:NSJSONReadingMutableContainers
error:nil];
NSLog(@"%@", array);
}
练习:
1:创建一个数组,数组成员是两个字典对象dictionary1和dictionary2,和一个数组对象array3
dictionary1中有:
@“chen chao”,@“name”
@“18”,@“age”
@“Good Teacher”,@“info”三个键值对(前面是value后面是key)
dictionary2中有:
@“liu de hua”,@“name”
@“56”,@“age”
@“actor”,@“info”三个键值对
array3成员是@“bei”,@“jing”,@“huan”,@“ying”,@“nin”
把该数组持久化到一个plist文件中,并读取plist文件中内容
2:创建一个字典,字典中有
array1, @“key1”
array2, @“key2”
dictionary3, @“key3”
array4, @“key4”四个键值对
array1数组成员有:@“ni”, @“hao”
array2数组成员有:@“bei”, @“jing”
dictionary3中有:
@“liu de hua”,@“name”
@“56”,@“age”
@“actor”,@“info”三个键值对
array4数组成员有:@“ying”, @“nin”,@“hao”,@“ma”
将该字典写入到list文件中,并读取plist文件中内容
3:分别创建一个NSString和NSArray和NSDictionary对象,并对该对象进行归档和反归档操作
4:创建一个自定义Person,成员是age和name,实现person类对象的归档反归档
ww文件和目录的操作和管理的基本知识
1:什么是文件和目录
文件:file
目录:dir
2:单例模式
1:什么是单例模式
单例模式是一种常见的设计模式,对于单例对象的类,必须要保证在任意时刻下只有一个对象存在,而且自行实例化该对象,并向整个系统提供这个对象。也就是说对于一个单例类无论实例化对象多少次都只有一个实例对象存在,并且这个对象是全局的,能够被整个系统访问到。
单例对象和c中的全局变量很相似。c中的全局变量可以实现在不同函数之间的数据共享,单例对象可以实现在不同对象之间的数据共享
2:单例对象的创建方式
一般类方式,并且
shared/default/current 开头
3:单例模式的应用
1:在不同对象之间数据共享
2:当创建一个类的时候需要耗费很大的性能时,这时候可以把这个类设计成单例类
3:Xcode中自己创建一个单例类
例子:
创建一个NormalClass类,类中有属性name,实例化出两个对象,给对象一的name赋值,打印两个对象的地址和属性值
创建一个SingleClass类,类中有属性name,实例化出两个对象,给对象一的name赋值,打印两个对象的地址和属性值
NormalClass类
NormalClass.h
#import <Foundation/Foundation.h>
@interface NormalClass :
NSObject
@property (copy,
nonatomic)NSString *name;
@end
NormalClass.m
#import "NormalClass.h"
@implementation NormalClass
@end
SingleClass类
SingleClass.h
#import <Foundation/Foundation.h>
@interface SingleClass :
NSObject
@property (copy,
nonatomic)NSString *name;
+ (SingleClass *)sharedSingleClass;//创建单例对象的方法
@end
SingleClass.m
#import "SingleClass.h"
//1:创建一个静态的全局单例对象并且初始化为nil
static SingleClass *single =
nil;
@implementation SingleClass
+ (SingleClass *)sharedSingleClass{
//2:调用GCD的once方法
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{//block//保证{}里面的代码在整个程序运行期间只被执行一次
//3:对象单例对象进行实例化
single = [[SingleClass
alloc] init];
});
return
single;//第一次调用该方法的时候返回实例化后的对象//从第二次开始返回的都是第一次实例化的对象
}
main.m
#import <Foundation/Foundation.h>
#import "NormalClass.h"
#import "SingleClass.h"
int main(int argc,
const char * argv[])
{
@autoreleasepool {
NormalClass *normal1 = [[NormalClass
alloc] init];//实例化对象
NormalClass *normal2 = [[NormalClass
alloc] init];
//1:打印两个对象的地址值不同,说明这两个对象是不同的对象
NSLog(@"normal1 = %p", normal1);
NSLog(@"normal2 = %p", normal2);
//2:修改某个对象的实例变量值,对另一个对象没有影响,说明这是两个不同的对象
normal1.name =
@"chen chao";
NSLog(@"normal1.name = %@", normal1.name);
NSLog(@"normal2.name = %@", normal2.name);
SingleClass *single1 = [SingleClass
sharedSingleClass];//创建单例对象
SingleClass *single2 = [SingleClass
sharedSingleClass];//创建单例对象
//1:打印两个单例类对象地址相同,说明这两个是同一个对象
NSLog(@"single1 = %p", single1);
NSLog(@"single2 = %p", single2);
//修改某个对象的值,另个对象也跟着一起改,说明两个对象是同一个对象
single1.name =
@"chen chao";
NSLog(@"single1.name = %@", single1.name);
NSLog(@"single2.name = %@", single2.name);
}
return 0;
}
练习:
创建一个PersonNormal非单例类,有一个两个属性int _age和NSString *_name;请用这个非单例的Person类创建两个对象,给一个对象的age和name属性赋值,通过打印观察是否影响另一个对象的值,并打印两个对象的地址
创建一个PersonSingle单例类,有一个两个属性int _age和NSString *_name;请用这个非单例的Person类创建两个对象,给一个对象的age和name属性赋值,通过打印观察是否影响另一个对象的值,并打印两个对象的地址
PersonNormal类
PersonNormal.h
#import <Foundation/Foundation.h>
@interface PersonNormal :
NSObject
@property (assign,
nonatomic)int age;
@property (copy,
nonatomic)NSString *name;
@end
PersonNormal.m
#import "PersonNormal.h"
@implementation PersonNormal
@end
PersonSingle类
PersonSingle.h
#import <Foundation/Foundation.h>
@interface PersonSingle :
NSObject
@property (assign,
nonatomic)int age;
@property (copy,
nonatomic)NSString *name;
+ (id)sharedPersonSingle;
@end
PersonSingle.m
#import "PersonSingle.h"
static PersonSingle *single =
nil;
@implementation PersonSingle
+ (id)sharedPersonSingle{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{//block
single = [[PersonSingle
alloc] init];
});
return single;
}
@end
main.m
#import <Foundation/Foundation.h>
#import "PersonNormal.h"
#import "PersonSingle.h"
int main(int argc,
const char * argv[])
{
@autoreleasepool {
PersonNormal *normal1 = [[PersonNormal
alloc] init];
PersonNormal *normal2 = [[PersonNormal
alloc] init];
NSLog(@"normal1 = %p", normal1);
NSLog(@"normal2 = %p", normal2);
normal1.age =
18;
normal1.name =
@"chen chao";
NSLog(@"normal1.age is %d normal1.name is %@", normal1.age,
normal1.name);
NSLog(@"normal2.age is %d normal2.name is %@", normal2.age,
normal2.name);
PersonSingle *single1 = [PersonSingle
sharedPersonSingle];
PersonSingle *single2 = [PersonSingle
sharedPersonSingle];
NSLog(@"single1 = %p", single1);
NSLog(@"single2 = %p", single2);
single1.age =
56;
single1.name =
@"zhang xue you";
NSLog(@"single1.age is %d single1.name is %@", single1.age,
single1.name);
NSLog(@"single2.age is %d single2.name is %@", single2.age,
single2.name);
}
return 0;
}
NSData和NSString之间的互相转换
#import <Foundation/Foundation.h>
int main(int argc,
const char * argv[])
{
@autoreleasepool {
NSString *string =
@"bei jing huan ying nin";
//- (NSData *)dataUsingEncoding:(NSStringEncoding)encoding; // External representation
//作用:将string转换成data
//encoding:编码格式
NSData *dataFromString = [string
dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"dataFromString = %@", dataFromString);
//- (instancetype)initWithData:(NSData *)data encoding:(NSStringEncoding)encoding;
//作用:将string转换成data
NSString *stringFromData = [[NSString
alloc] initWithData:dataFromString
encoding:NSUTF8StringEncoding];
NSLog(@"stringFromData = %@", stringFromData);
}
return 0;
}
文件和目录管理
1:什么文件和目录管理
文件目录管理:就是指文件和目录的创建,目录的遍历,文件目录的复制,剪切,删除等
2:文件管理器对象的创建(单例对象)
NSFileManager * fm = [NSFileManager
defaultManager];
//文件管理器的创建
void createFileManage(void){
//fileManage对象一旦创建完成后,后续所有的文件操作都是通过fileManage进行操作的
NSFileManager *fileManage = [NSFileManager
defaultManager];//创建一个单例类的对象
}
3:文件和目录的创建
//创建普通文件//如果两个文件的文件名相同时,创建成功,但是会用新文件覆盖旧的文件
- (BOOL)createFileAtPath:(NSString
*)path contents:(NSData *)data attributes:(NSDictionary *)attr;
//创建目录//第二个参数是:当子路径不存在时是否创建子路径
- (BOOL)createDirectoryAtPath:(NSString
*)path withIntermediateDirectories:(BOOL)createIntermediates attributes:(NSDictionary *)attributes error:(NSError **)error ;
//文件和目录的创建
void createFileAndDir(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileManager *fileManage = [NSFileManager
defaultManager];
//- (BOOL)createFileAtPath:(NSString *)path contents:(NSData *)data attributes:(NSDictionary *)attr;
//作用:创建文件
//path:创建的文件路径
//data:创建文件开始时给文件添加内容,如果时nil,创建的文件就是空文件
//attr:文件属性
[fileManage createFileAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]
contents:nil
attributes:nil];
//- (BOOL)createDirectoryAtPath:(NSString *)path withIntermediateDirectories:(BOOL)createIntermediates attributes:(NSDictionary *)attributes error:(NSError **)error NS_AVAILABLE(10_5, 2_0);
//作用:创建目录
//path:目录的路径
//createIntermediates:如果创建的路径的子路径不存在时,是否连同子路径一起创建
//attributes:文件属性
//error:如果创建失败,保存创建失败的原因
NSError *error =
nil;
[fileManage createDirectoryAtPath:[pathDesktop
stringByAppendingString:@"/dir/dir1"]
withIntermediateDirectories:NO
attributes:nil
error:&error];
if (error) {
NSLog(@"创建目录失败 : %@",
[error localizedFailureReason]);
}
}
withIntermediateDirectories:NO
如果是no的话没有路径中没有dir文件或者目录,则不能完成创建dir1,如果是YES,则自动创建路径包含的中间的文件夹dir
4:目录的遍历(traverse)
//浅度遍历
- (NSArray *)contentsOfDirectoryAtPath:(NSString
*)path error:(NSError **)error;
//深度遍历
- (NSArray *)subpathsOfDirectoryAtPath:(NSString
*)path error:(NSError **)error
//目录的遍历
void traverseDir(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileManager *fileManage = [NSFileManager
defaultManager];
//- (NSArray *)contentsOfDirectoryAtPath:(NSString *)path error:(NSError **)error NS_AVAILABLE(10_5, 2_0);
//作用:浅层遍历,只能遍历一层
NSArray *arrayContent = [fileManage
contentsOfDirectoryAtPath:[pathDesktop
stringByAppendingString:@"/dir"]
error:nil];
NSLog(@"%@", arrayContent);
//- (NSArray *)subpathsOfDirectoryAtPath:(NSString *)path error:(NSError **)error NS_AVAILABLE(10_5, 2_0);
//作用:深层遍历,一直遍历到最后一层
NSArray *arraySub = [fileManage
subpathsOfDirectoryAtPath:[pathDesktop
stringByAppendingString:@"/dir"]
error:nil];
NSLog(@"%@", arraySub);
}
练习1:深层遍历目录下所有文件,并找出以.txt为后缀的文件,将文件名输出
//练习1:深层遍历目录下所有文件,并找出以.txt为后缀的文件,将文件名输出
void test1(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileManager *fileManage = [NSFileManager
defaultManager];
NSArray *arraySub = [fileManage
subpathsOfDirectoryAtPath:[pathDesktop
stringByAppendingString:@"/dir"]
error:nil];//保存所有文件的文件名
for (NSString *fileName
in arraySub) {
if ([fileName
hasSuffix:@"txt"]) {
NSLog(@"%@", fileName);
}
}
}
5:复制文件和目录
//srcPath:原文件路径
//dstPath:新文件路径
- (BOOL)copyItemAtPath:(NSString
*)srcPath toPath:(NSString *)dstPath error:(NSError **)error ;
//复制文件或目录
void copyFileAndDir(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileManager *fileManage = [NSFileManager
defaultManager];
//- (BOOL)copyItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error NS_AVAILABLE(10_5, 2_0);
//作用:文件或目录的复制
//复制文件
[fileManage copyItemAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]
toPath:[pathDesktop stringByAppendingString:@"/dir/fileCopy.txt"]
error:nil];
[fileManage copyItemAtPath:[pathDesktop
stringByAppendingString:@"/dir/dir1"]
toPath:[pathDesktop stringByAppendingString:@"/dir1Copy"]
error:nil];
}
6:剪切(cut)文件和目录
- (BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString
*)dstPath error:(NSError **)error ;
//剪切文件或目录
void cutFileAndDir(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileManager *fileManage = [NSFileManager
defaultManager];
//- (BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error NS_AVAILABLE(10_5, 2_0);
//作用:剪切文件或目录
[fileManage moveItemAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]
toPath:[pathDesktop stringByAppendingString:@"/dir/dir1/fileCut.txt"]
error:nil];
}
7:删除文件和目录
- (BOOL)removeItemAtPath:(NSString
*)path error:(NSError **)error;
//删除文件或目录
void deleteFileAndDir(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileManager *fileManage = [NSFileManager
defaultManager];
//- (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error NS_AVAILABLE(10_5, 2_0);
//作用:删除文件或目录
[fileManage removeItemAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]
error:nil];
}
8:获取文件属性(attribute)
- (NSDictionary *)attributesOfItemAtPath:(NSString
*)path error:(NSError **)error;
//获取文件的属性
void getAttribute(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileManager *fileManage = [NSFileManager
defaultManager];//创建单例对象
//- (NSDictionary *)attributesOfItemAtPath:(NSString *)path error:(NSError **)error NS_AVAILABLE(10_5, 2_0);
//作用:获取文件或目录的相关属性
NSDictionary *dictionaryFile = [fileManage
attributesOfItemAtPath:[pathDesktop stringByAppendingString:@"/file.txt"]
error:nil];
NSDictionary *dictionaryDir = [fileManage
attributesOfItemAtPath:[pathDesktop stringByAppendingString:@"/dir"]
error:nil];
NSLog(@"%@", dictionaryFile);
NSLog(@"%@", dictionaryDir);
}
9:判断文件是否存在
- (BOOL)fileExistsAtPath:(NSString
*)path;
//判断文件是否存在
void isHaveFileOrDir(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileManager *fileManage = [NSFileManager
defaultManager];//创建单例对象
if ([fileManage
fileExistsAtPath:[pathDesktop stringByAppendingString:@"/file.txt"]]) {
NSLog(@"有这个文件");
} else {
NSLog(@"没有这个文件");
}
}
练习2:打印目录下所有文件和目录的大小(包括子路径下的文件和目录)。
//练习2:打印目录下所有文件和目录的大小(包括子路径下的文件和目录)。
void test2(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileManager *fileManage = [NSFileManager
defaultManager];//创建单例对象
//遍历所有子目录(深层遍历)
NSArray *arraySub = [fileManage
subpathsOfDirectoryAtPath:[pathDesktop
stringByAppendingString:@"/dir"]
error:nil];
for (NSString *fileName
in arraySub) {//取出每个文件或目录
NSLog(@"%@", fileName);
NSDictionary *dictionary = [fileManage
attributesOfItemAtPath:[[[pathDesktop stringByAppendingString:@"/dir"]
stringByAppendingString:@"/"]
stringByAppendingString:fileName] error:nil];
NSLog(@"%@", [dictionary
objectForKey:@"NSFileSize"]);
}
}
练习3:
1:创建一个文件夹dir
2:创建一个文件file.txt
create
3:将file.txt复制一份带dir中,复制后文件叫fileCopy.txt
copy
4:将file.txt剪切一份带dir中,复制后文件叫fileCut.txt
move
5:遍历dir下所有文件,打印每个文件的所有属性信息,并提出出文件大小
sub
/*
练习3:
1:创建一个文件夹dir
2:创建一个文件file.txt
create
3:将file.txt复制一份带dir中,复制后文件叫fileCopy.txt
copy
4:将file.txt剪切一份带dir中,复制后文件叫fileCut.txt
move
5:遍历dir下所有文件,打印每个文件的所有属性信息,并提出出文件大小
sub
*/
void test4(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileManager *fileManage = [NSFileManager
defaultManager];//创建单例对象
//1:创建文件夹dir
[fileManage createDirectoryAtPath:[pathDesktop
stringByAppendingString:@"/dir"]
withIntermediateDirectories:YES
attributes:nil
error:nil];
//2:创建文件file.txt
[fileManage createFileAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]
contents:nil
attributes:nil];
//3:将file.txt复制一份带dir中,复制后文件叫fileCopy.txt
[fileManage copyItemAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]
toPath:[pathDesktop stringByAppendingString:@"/dir/fileCopy.txt"]
error:nil];
//4:将file.txt剪切一份带dir中,复制后文件叫fileCut.txt
[fileManage moveItemAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]
toPath:[pathDesktop stringByAppendingString:@"/dir/fileCut.txt"]
error:nil];
}
文件操作
1:什么是文件操作
文件操作:就是指对文件的打开,文件内容的读、写、设置偏移量和同步
2:文件的打开
//以只读方式打开
+ (id)fileHandleForReadingAtPath:(NSString *)path;
//以只写方式打开
+ (id)fileHandleForWritingAtPath:(NSString *)path;
//以读写方式打开
+ (id)fileHandleForUpdatingAtPath:(NSString *)path;
//文件的打开
void openFile(void){
//注意:NSFileHandle对象创建完成后,后续所有对文件内的操作都是通过NSFileHandle对象来完成的
NSString *pathDesktop =
@"/Users/mac/Desktop";
//+ (id)fileHandleForReadingAtPath:(NSString *)path;
//作用:以只读的方式打开文件
NSFileHandle *fileHandleRead = [NSFileHandle
fileHandleForReadingAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]];
//+ (id)fileHandleForWritingAtPath:(NSString *)path;
//作用:以只写的方式打开文件
NSFileHandle *fileHandleWrite = [NSFileHandle
fileHandleForWritingAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]];
//+ (id)fileHandleForUpdatingAtPath:(NSString *)path;
//作用:以读写的方式打开文件
NSFileHandle *fileHandleUp = [NSFileHandle
fileHandleForUpdatingAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]];
}
3:文件内容的读取
1:读取指定长度的数据
- (NSData *)readDataOfLength:(NSUInteger)length;
2:从当前偏移量读到文件末尾
- (NSData *)readDataToEndOfFile;
//文件内容的读取
void readFile(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileHandle *fileHandle = [NSFileHandle
fileHandleForUpdatingAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]];//以读写的方式打开文件
#if 0
//- (NSData *)readDataOfLength:(NSUInteger)length;
//作用:读取文件中指定长度的数据
NSData *dataFromFile = [fileHandle readDataOfLength:6];
NSString *stringFromData = [[NSString alloc] initWithData:dataFromFile encoding:NSUTF8StringEncoding];//把data转换成string
NSLog(@"%@", stringFromData);
#endif
//- (NSData *)readDataToEndOfFile;
//作用:读取文件中所有的数据
NSData *dataFromFile = [fileHandle
readDataToEndOfFile];
NSString *stringFromData = [[NSString
alloc] initWithData:dataFromFile
encoding:NSUTF8StringEncoding];
NSLog(@"%@", stringFromData);
}
4:写文件
- (void)writeData:(NSData
*)data;
//向文件中写数据
void writeDataToFile(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileHandle *fileHandle = [NSFileHandle
fileHandleForUpdatingAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]];//以读写的方式打开文件
NSString *string =
@"chen chao zui shuai";
NSData *dataFromString = [string
dataUsingEncoding:NSUTF8StringEncoding];//将string转换成data
//- (void)writeData:(NSData *)data;
//作用:向文件中写数据(覆盖之前内容)
[fileHandle writeData: dataFromString];
//思考:文件末尾出写入@"chen chao ni zui shuai"
NSLog(@"%@", [[NSString
alloc] initWithData:[fileHandle
readDataOfLength:5]
encoding:NSUTF8StringEncoding]);
}
思考:如果想在文件末尾添加内容时,该如何处理?
5:设置文件偏移量
1:将文件偏移量设置到文件中的指定位置
- (void)seekToFileOffset:(unsigned
long long)offset;
2:将文件偏移量设置到文件末尾
- (unsigned
long long)seekToEndOfFile;
//设置文件偏移量
void setFileSeek(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";//桌面路径
NSFileHandle *fileHandle = [NSFileHandle
fileHandleForUpdatingAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]];//以读写的方式打开文件
[fileHandle seekToFileOffset:5];//设置文件偏移量到指定位置
[fileHandle seekToEndOfFile];//设置文件偏移量到文件末尾
NSLog(@"%@", [[NSString
alloc] initWithData:[fileHandle
readDataOfLength:4]
encoding:NSUTF8StringEncoding]);
}
练习3:在文件末尾写入新的信息并将整个文件内容读取后输出
//1:打开文件
//2:设置便宜量到文件末尾
//3:写入数据
//4:设置偏移量到文件开始
//5:读取文件内容
void test3(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";
//1:打开文件
NSFileHandle *fileHandle = [NSFileHandle
fileHandleForUpdatingAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]];
//2:设置便宜量到文件末尾
[fileHandle seekToEndOfFile];
//3:写入数据
NSString *string =
@"liu de hua mei wo shuai";
NSData *dataFromString = [string
dataUsingEncoding:NSUTF8StringEncoding];
[fileHandle writeData:dataFromString];
//4:设置偏移量到文件开始
[fileHandle seekToFileOffset:0];
//5:读取文件内容
NSData *dataFromFile = [fileHandle
readDataToEndOfFile];
NSString *stringFromData = [[NSString
alloc] initWithData:dataFromFile
encoding:NSUTF8StringEncoding];
NSLog(@"%@", stringFromData);
}
练习4:在文件开始处和文件末尾处添加字符串@“chen chao ni zui shuai”,添加完成后读取文件所有内容并输出
sdkljfhslkdfjgl
//1:打开文件
//2:读取文件中所有内容
//3:拼接
//4:设置偏移量到文件开始
//5:写入拼接后的信息
//6:写入字符串
//7:设置偏移量到文件开始
//8:读取文件内容
/*
练习4:在文件开始处和文件末尾处添加字符串@“chen chao ni zui shuai”,添加完成后读取文件所有内容并输出
sdkljfhslkdfjgl
//1:打开文件
//2:读取文件中所有内容
//3:拼接
//4:设置偏移量到文件开始
//5:写入拼接后的信息
//6:写入字符串
//7:设置偏移量到文件开始
//8:读取文件内容
*/
void test5(void){
NSString *pathDesktop =
@"/Users/mac/Desktop";
//1:打开文件
NSFileHandle *fileHandle = [NSFileHandle
fileHandleForUpdatingAtPath:[pathDesktop
stringByAppendingString:@"/file.txt"]];
//2:读取文件中所有内容
NSData *dataFromFile = [fileHandle
readDataToEndOfFile];
//3:拼接
NSString *string =
@"chen chao ni zui shuai";
NSString *stringFromData = [[NSString
alloc] initWithData:dataFromFile
encoding:NSUTF8StringEncoding];
NSString *stringToFile = [string
stringByAppendingString:stringFromData];
//4:设置偏移量到文件开始
[fileHandle seekToFileOffset:0];
//5:写入拼接后的信息
NSData *dataToFile = [stringToFile
dataUsingEncoding:NSUTF8StringEncoding];
[fileHandle writeData:dataToFile];
//6:写入字符串
NSData *dataToFileString = [string
dataUsingEncoding:NSUTF8StringEncoding];
[fileHandle writeData:dataToFileString];
//7:设置偏移量到文件开始
[fileHandle seekToFileOffset:0];
//8:读取文件内容
NSData *dataFromFileAll = [fileHandle
readDataToEndOfFile];
NSString *stringAll = [[NSString
alloc] initWithData:dataFromFileAll
encoding:NSUTF8StringEncoding];
NSLog(@"%@", stringAll);
}
课后练习:
练习1:创建一个Human单例类
练习2:把字符串@“chen chao”变成NSData类型对象,并将NSData对象转换成NSString后输出
#import <Foundation/Foundation.h>
int main(int argc,
const char * argv[])
{
@autoreleasepool {
NSString *string =
@"chen chao";
NSData *dataFromString = [string
dataUsingEncoding:NSUTF8StringEncoding];//将字符串转成NSData
NSString *stringFromData = [[NSString
alloc] initWithData:dataFromString
encoding:NSUTF8StringEncoding];//将NSData对象转换成字符串
NSLog(@"string = %@", string);
NSLog(@"stringFromData = %@", stringFromData);
}
return 0;
}
练习3:在桌面上创建一个temp文件夹和file.txt文件,将file.txt剪切到temp文件夹下,将字符串@“chen chao ni zui shuai”写入到文件file.txt,并读取文件内容,输出
void test5(void){
//创建文件管理器
NSString *pathDestop =
@"/Users/mac/Desktop";
NSFileManager *fileManage = [NSFileManager
defaultManager];
//创建目录
[fileManage createDirectoryAtPath:[pathDestop
stringByAppendingString:@"/temp"]
withIntermediateDirectories:YES
attributes:nil
error:nil];
//创建文件
[fileManage createFileAtPath:[pathDestop
stringByAppendingString:@"/file.txt"]
contents:nil
attributes:nil];
//将文件剪切到tmp目录下
[fileManage moveItemAtPath:[pathDestop
stringByAppendingString:@"/file.txt"]
toPath:[pathDestop stringByAppendingString:@"/temp/file.txt"]
error:nil];
//创建文件操作
NSFileHandle *fileHandle = [NSFileHandle
fileHandleForUpdatingAtPath:[pathDestop
stringByAppendingString:@"/temp/file.txt"]];
//将字符串写入文件
NSString *string =
@"chen chao ni zui shuai";
NSData *data = [string
dataUsingEncoding:NSUTF8StringEncoding];
[fileHandle writeData:data];
//将文件偏移量设置到文件开始处
[fileHandle seekToFileOffset:0];
//读取文件信息
NSData *dataFromFile = [fileHandle
readDataToEndOfFile];
NSString *stringFromData = [[NSString
alloc] initWithData:dataFromFile
encoding:NSUTF8StringEncoding];
NSLog(@"%@", stringFromData);
}
一、做一个单例
1、做一个单例类,SingleClass
2、singleClass有一个属性,_name(NSString)
3、做一个普通类 NormalClass
4、NormalClass有一个属性,_name(NSString)
5、分别实例化出两个单例类和普通类对象,分别给一个对象的name赋值,打印两个对象的地址和成员值进行比较,总结单例的特点
二、有一个字符串@“123”,把这个字符串转为data,再转回字符串
三、
1、在桌面上创建一个文件夹“page”
2、在page文件夹中创建一个文件夹“my”
3、在my文件夹中,创建一个文件“book.txt”
4、把“book.txt”复制到page文件夹中
5、深度遍历page文件夹并打印
四、
1、在Documents中创建一个文件“class1435.txt”
2、读写方式打开class1435.txt并write“我是中国人”进去
3、把偏移量挪回开头,并读出这个文件字符串内容
4、把文件中的字符串“我是中国人”改成“我还是中国人”
5、读出整个文件字符串内容
五、
遍历桌面上的dir目录,找出里面所有已.txt路径结尾文件,并且读取文件所有信息
———————————————————————————
内存管理
在内存中干3件事:
1、开辟存储空间
2、初始化成员变量
3、返回指针地址
内存回收机制:
手动引用计数和自动释放池
自动引用计数(ARC)
自动垃圾回收(iOS系统不支持垃圾回收
ARC:ARC机制管理内存,它的弊端:系统无法正确识别自定义对象是否还会继续使用,会提前释放,导致程序崩溃
gar— —>object-C atomic Refrence— —>BOOL
MRC:
内存管理黄金法则:
1、关键字:alloc , retain, [mutable] copy, new
2、谁持有,谁管理(/谁污染,谁治理)
autorelease:做的是入池工作 ——》autoreleasepool
在手动引用计数中,改变对象的引用计数的方式如下:
当程序调用方法名以alloc、new、copy、 mutableCopy开头的方法来创建对象时,该对象的引用计数加1。
retain:将该对象的引用计数器加1
release:将该对象的引用计数器减1
autorelease:不改变该对象的引用计数器的值,只是将对象添加到自动释放池中
retainCount:返回该对象的引用计数的值
内存管理:
基本数据 assign【默认参数】非OC对象类型可以使用
对象 retain//保留对象的所有权 OC的对象类型使用+1
字符串 copy NSString类型
arc:
strong的含义和retain相同,weak和assign相同,修饰完的属性变量用法也是完全没有改变,不过strong和weak只能修饰对象。
线程方面:
nonatomic 线程不安【默认参数】
atomic 线程安全
方法生成
readonly
readwrite【默认参数】
@property修饰符展开
assign:直接赋值,不做任何内存管理(默认,用于非oc对象)
retain: release旧值,retain新值(用于oc对象)
copy:release旧值,copy新值(一般用于string )
______________________________________________
KVC(key value coding)
【对象 setValue:(id) forKey:(NSString *)】;
KVO(key value observe观察)
监听
MVC
架构模式(设计模式)
M 模型 数据模型 数据逻辑 网络处理
C 视图控制器
V 视图 展示UI 交互 UILable/UIButton……
——————————————————————————————
//日期与时间(NSDate)
//date当前日期
NSDate *date=[NSDate
date];
NSLog(@"当前时间:%@",date);
//date1 date2
从当前时间开始,一天后的日期
NSDate * date1=[[NSDate
alloc]initWithTimeInterval:3600*24
sinceDate:date];
NSLog(@"当前时间:%@",date1);
NSDate * date2=[[NSDate
alloc]initWithTimeIntervalSinceNow:3600*24];
NSLog(@"当前时间:%@",date2);
//获取当前时间,3天之前的日期
NSDate * date3=[[NSDate
alloc]initWithTimeIntervalSinceNow:-3*3600*24];
NSLog(@"当前时间:%@",date3);
//获取从1970年1月1日开始,20年之后的日期
NSDate * date4=[[NSDate
alloc]initWithTimeIntervalSince1970:3600*24*366*20];
NSLog(@"从1970年1月1日开始,20年之后的日期%@",date4);
//获取对应时间的字符串
NSLocale *cn=[NSLocale
currentLocale];
NSLog(@"对应时间的字符串%@",
[date descriptionWithLocale:cn]);
NSLocale代表一个语言、国际环境(比如大陆的简体中文)
//获取两个日期之间较早的日期
NSData *earlier=[date
earlierDate:date4];;
NSLog(@"两个日期之间较早的日期:%@",earlier);
//获取两个日期之间较晚的日期
NSData *later=[date
laterDate:date1];
NSLog(@"两个日期之间较晚的日期%@",later);
//date
和date1之间的时间差
NSLog(@"两个时间之间的时间差%g秒",[date
timeIntervalSinceDate:date1]);
//获取指定时间与现在的时间差
NSLog(@"指定时间与现在的时间差%g秒",[date1
timeIntervalSinceNow]);
ter);
//日期格式器(NSDateFormatter)
//date当前日期
NSDate *dt=[NSDate
date];
NSLog(@"当前时间:%@",dt);
//分别代表中国
美国
NSLocale *locales[]={[[NSLocale
alloc]initWithLocaleIdentifier:@"中国时间:"],[[NSLocale
alloc]initWithLocaleIdentifier:@"美国时间:"]};
NSDateFormatter *df[8];
//为上面2个NSLocale创建8个DateFormat对象
for (int i=0; i<2; i++) {
df[i*4]=[[NSDateFormatter
alloc]init];
//设置NSDateFormatter的日期、时间风格
[df[i*4]setDateStyle:NSDateFormatterShortStyle];
[df[i*4]setTimeStyle:NSDateFormatterShortStyle];
//设置NSDateFormatter的NSLocale
[df[i*4]setLocale:locales[i]];
df[i*4+1]=[[NSDateFormatter
alloc]init];
[df[i*4+1]setDateStyle:NSDateFormatterMediumStyle];
[df[i*4+1]setTimeStyle:NSDateFormatterMediumStyle];
//设置NSDateFormatter的NSLocale
[df[i*4+1]setLocale:locales[i]];
df[i*4+2]=[[NSDateFormatter
alloc]init];
[df[i*4+2]setDateStyle:NSDateFormatterLongStyle];
[df[i*4+2]setTimeStyle:NSDateFormatterLongStyle];
//设置NSDateFormatter的NSLocale
[df[i*4+2]setLocale:locales[i]];
df[i*4+3]=[[NSDateFormatter
alloc]init];
[df[i*4+3]setDateStyle:NSDateFormatterFullStyle];
[df[i*4+3]setTimeStyle:NSDateFormatterFullStyle];
//设置NSDateFormatter的NSLocale
[df[i*4+3]setLocale:locales[i]];
for (int i=0; i<2; i++) {
switch (i) {
case
0:
NSLog(@"----中国日期格式----");
break;
case
1:
NSLog(@"----美国日期格式----");
break;
}
NSLog(@"short:%@",[df[i*4]
stringFromDate:dt]);
NSLog(@"mdi:%@",[df[i*4+1]
stringFromDate:dt]);
NSLog(@"long:%@",[df[i*4+2]
stringFromDate:dt]);
NSLog(@"full:%@",[df[i*4+3]
stringFromDate:dt]);
}
NSDateFormatter *df2=[[NSDateFormatter
alloc]init];
//设置自定义的格式器模板
[df2 setDateFormat:@"公元yyyy年MM月DD日
HH时mm分"];
//执行格式化
NSLog(@"**%@",[df2
stringFromDate:dt]);
NSString *dateStr=@"2013-03-02";
NSDateFormatter *df3=[[NSDateFormatter
alloc]init];
//根据日期字符串的格式设置格式模板
[df3 setDateFormat:@"yyyy-MM-DD HH时mm分"];
//将字符串转换为NSDate对象
NSDate *date2=[df3
dateFromString:dateStr ];
NSLog(@"%@",date2);
//定时器
[NSTimer scheduledTimerWithTimeInterval:<#(NSTimeInterval)#> invocation:<#(NSInvocation *)#> repeats:];
NSTimer scheduledTimerWithTimeInterval:<#(NSTimeInterval)#> target:<#(id)#> selector:<#(SEL)#> userInfo:<#(id)#> repeats:<#(BOOL)#>
//timeInterval:指定每隔多少秒执行一次任务
//invocation或target或selector:指定重复执行的任务
//userUnfo:该参数用于指定用某个对象的特定方法作为重复至ing的任务
//repeats:控制是否需要重复执行任务。
[timer invalidate];//销毁定时器
——————————————
1.Objective-C中,与alloc语义相反的方法是dealloc还是release?与retain语义相反的方法是dealloc还是release,为什么?需要与alloc配对使用的方法是dealloc还是release,为什么?
答:alloc与dealloc语意相反,alloc是创建变量,dealloc是释放变量。
retain 对应release,retain
保留一个对象。调用之后,变量的计数加1。
2.在一个对象的方法里面:
self.name = “object”;
和
name =”object”
有什么不同吗?
答:self.name = "object"会调用对象的setName()方法,name = "object"会直接把object赋值给当前对象的name
属性。
4.什么是retain count?
答:引用计数(ref count或者retain count)。对象的内部保存一个数字,表示被引用的次数。例如,某个对象被两个指针所指向(引用)那么它的retain count为2。需要销毁对
象的时候,不直接调用dealloc,而是调用release。release会
让retain count减1,只有retain count等于0,系统才会调用dealloc真正销毁这个对象。
6.为什么很多内置类如UITableViewController的delegate属性都是assign而不是retain的?
答:会引起循环引用。
14.什么是KVC和KVO?
答:KVC(Key-Value-Coding)内部的实现:一个对象在调用setValue的时候,(1)首先根据方法名找到运行方法的时候所需要的环境参数。(2)他会从自己isa指针结合环境参数,找到具体的方法实现的接口。(3)再直接查找得来的具体的方法实现。KVO(Key-Value-Observing):当观察者为一个对象的属性进行了注册,被观察对象的isa指针被修改的时候,isa指针就会指向一个中间类,而不是真实的类。所以isa指针其实不需要指向实例对象真实的类。所以我们的程序最好不要依赖于isa指针。在调用类的方法的时候,最好要明确对象实例的类名。
13.线程与进程的区别和联系?
进程和线程都是由操作系统所体会的程序运行的基本 单元,系统利用该基本单元实现系统对应用的并发性。
程和线程的主要差别在于它们是不同的操作系统资源 管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变
量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一
些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程
相关文章推荐
- Objective-C( Foundation框架 一 数组(NSMutableArray))
- Objective-C( Foundation框架 一 数组(NSArray))
- 17.setValue和setObject的区别
- js window object
- objectiveC【语法】修饰符 static extern const
- Objective-C学习笔记12:高级数据类型一
- Objective-C学习笔记11:多态和动态类型
- Objective-C学习笔记十:继承二
- Objective-C学习笔记九:继承一
- Objective-C学习笔记八:类的定义二
- Objective-C学习笔记七:类的定义一
- Objective-C学习笔记六:选择结构二
- Objective-C学习笔记五:选择结构一
- Objective-C学习笔记四:循环结构
- Objective-C学习笔记三:基本数据类型和表达式
- Objective-C学习笔记二:面向对象概述
- Objective-C学习笔记一:第一个应用程序
- ActiveXObject Word.Application 打印小票
- 使用原生sql查询数据返回object类型list时,转换数据列出现转换类型错误(但写法正确)
- 编写高质量Objective-C代码