UIView动画
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| [UIView animateWithDuration:1 delay:1 options:UIViewAnimationOptionCurveLinear animations:^{ xxx } completion:^(BOOL finished) { xxx }]; animateWithDuration-动画持续时间 delay-动画延迟时间 options-动画渐入渐出 动画线性效果选择-options UIViewAnimationOptionCurveEaseInOut 匀加速-匀速-匀减速 UIViewAnimationOptionCurveEaseIn 匀加速-匀速 UIViewAnimationOptionCurveEaseOut 匀速-匀减速 UIViewAnimationOptionCurveLinear 匀速 animations-在动画持续时间内执行的变幻 completion-该动画持续时间结束后执行的下一步动作,可在此嵌套下一步动画
|
缩放
1
| _animationView.transform = CGAffineTransformScale(_animationView.transform, 0.5, 0.5);
|
旋转
1
| _animationView.transform = CGAffineTransformRotate(_animationView.transform, M_PI_4);
|
变换动作-翻转
1 2 3 4 5 6
| [UIView transitionWithView:_animationView duration:1 options:UIViewAnimationOptionCurveEaseIn | UIViewAnimationOptionTransitionFlipFromLeft animations:nil completion:nil];
options 多个可用 | 间隔 翻转独有线性效果选项 UIViewAnimationOptionTransitionFlipFromLeft UIViewAnimationOptionTransitionFlipFromRight
|
弹性动画
1 2 3 4 5 6 7 8
| usingSpringWithDamping 阻尼系数 0-1 越小越明显 initialSpringVelocity 初始速度
[UIView animateWithDuration:0.2 delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:0 options:0 animations:^{
} completion:^(BOOL finished){
}];
|
补充
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| UIViewAnimationOptions详细 UIViewAnimationOptionLayoutSubviews //动画过程中保证子视图跟随运动 UIViewAnimationOptionAllowUserInteraction //动画时允许用户交流,比如触摸 UIViewAnimationOptionBeginFromCurrentState //所有视图从当前状态开始动画 UIViewAnimationOptionRepeat //动画无限重复 UIViewAnimationOptionAutoreverse //动画运行到结束点后仍然以动画方式回到初始点,前提是设置动画无限重复 UIViewAnimationOptionOverrideInheritedDuration //忽略外层动画嵌套的执行时间 UIViewAnimationOptionOverrideInheritedCurve //忽略外层动画嵌套的时间变化曲线 UIViewAnimationOptionAllowAnimatedContent //通过改变属性和重绘实现动画效果,如果key没有提交动画将使用快照 UIViewAnimationOptionShowHideTransitionViews //用显隐的方式替代添加移除图层的动画效果 UIViewAnimationOptionOverrideInheritedOptions //不继承父动画设置或动画类型 时间函数曲线相关 UIViewAnimationOptionCurveEaseInOut //时间曲线函数,由慢到快 UIViewAnimationOptionCurveEaseIn //时间曲线函数,由慢到特别快 UIViewAnimationOptionCurveEaseOut //时间曲线函数,由快到慢 UIViewAnimationOptionCurveLinear //时间曲线函数,匀速 转场动画相关的 UIViewAnimationOptionTransitionNone //无转场动画 UIViewAnimationOptionTransitionFlipFromLeft //转场从左翻转 UIViewAnimationOptionTransitionFlipFromRight //转场从右翻转 UIViewAnimationOptionTransitionCurlUp //上卷转场 UIViewAnimationOptionTransitionCurlDown //下卷转场 UIViewAnimationOptionTransitionCrossDissolve //转场交叉消失 UIViewAnimationOptionTransitionFlipFromTop //转场从上翻转 UIViewAnimationOptionTransitionFlipFromBottom //转场从下翻转 关键帧 UIViewKeyframeAnimationOptionCalculationModeLinear UIViewKeyframeAnimationOptionCalculationModeDiscrete UIViewKeyframeAnimationOptionCalculationModePaced UIViewKeyframeAnimationOptionCalculationModeCubic UIViewKeyframeAnimationOptionCalculationModeCubicPaced
|
高级动画
CALayer 图层
初始化
1 2 3 4 5 6 7 8 9 10 11 12
| @property (nonatomic,strong) CALayer *layer; _layer = [CALayer layer]; _layer.backgroundColor = [UIColor colorWithRed:0.91 green:0.34 blue:0.31 alpha:1].CGColor; _layer.bounds = CGRectMake(0, 0, 50, 50); _layer.position = self.view.center;//设置中旬点 _layer.shadowColor = [UIColor colorWithRed:0.21 green:0.6 blue:0.93 alpha:1].CGColor; _layer.shadowOffset = CGSizeMake(3, 3); _layer.shadowOpacity = 0.8; 透明度 设置锚点,锚点的位置永远和中心点重合 默认(0.5,0.5),即中心点,按照比例取值,(0,0)左上角,(1,1)右下角 _layer.anchorPoint = CGPointMake(1, 1); [self.view.layer addSublayer:_layer];
|
重写触摸事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { [super touchesBegan:touches withEvent:event]; UITouch *touch = touches.anyObject; CGPoint touchPoint = [touch locationInView:self.view]; CGFloat width = _layer.bounds.size.width; if (width == 50) { width = 50 * 4; }else{ width = 50; } _layer.bounds = CGRectMake(0, 0, width, width); _layer.position = touchPoint; } 在使用CALayer 图层动画的时候,初始化之后的属性变化会自动以动画形式展现
|
CATransition 过渡动画
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| CATransition *animation = [CATransition animation]; 持续时间 animation.duration = 0.5; 线性规律 animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; /*私有API 不可用于上架 cube、suckEffect、oglFlip、rippleEffect、pageCurl、pageUnCurl cameraIrisHollowOpen、cameraIrisHollowClose */ animation.type = @"rippleEffect"; 过渡动画类型 kCATransition kCATransitionFade kCATransitionMoveIn kCATransitionPush kCATransitionReveal animation.type = kCATransitionPush;
配置转场动画子类型 animation.subtype = kCATransitionFromLeft; 添加动画 [self.view.layer addAnimation:animation forKey:@"transition"];
|
CABasicAnimation 基础动画
先确定基础动画的类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| CABasicAnimation *positionAnimation = [CABasicAnimation animationWithKeyPath:@"position"]; 持续时间 positionAnimation.duration = 0.5; 运动线性 positionAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; 动画的初始值-默认初始化的属性 positionAnimation.fromValue = [NSValue valueWithCGPoint:self.view.center]; 动画的终止值 positionAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(CGRectGetMidX(self.view.bounds), 100)]; 动画完成后是否回到原位,默认yes positionAnimation.removedOnCompletion = NO; positionAnimation.fillMode = kCAFillModeBoth; 决定当前对象在非active时间段的行为.比如动画开始之前,动画结束之后 kCAFillModeRemoved 这个是默认值,也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态 kCAFillModeForwards 当动画结束后,layer会一直保持着动画最后的状态. kCAFillModeBackwards 在动画开始前,你只要将动画加入了一个layer,layer便立即进入动画的初始状态并等待动画开始. 你可以这样设定测试代码,将一个动画加入一个layer的时候延迟5秒执行.然后就会发现在动画没有开始的时候,只要动画被加入了layer,layer便处于动画初始状态 kCAFillModeBoth 这个其实就是上面两个的合成.动画加入后开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状 添加动画 [self.view.layer addAnimation:positionAnimation forKey:@"position"];
|
animationWithKeyPath可选类型有
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| transform.scale 比例转换 transform.scale.x 宽的比例轉換 transform.scale.y 高的比例轉換 transform.rotation.z 平面园的旋轉 opacity 透明度 margin 边缘 zPosition backgroundColor 背景颜色 cornerRadius 圆角 borderWidth 边框宽度 bounds 大小 contents 内容 contentsRect 内容矩形 cornerRadius 圆角半径 frame 位置及尺寸 hidden 隐藏 mask 遮罩 masksToBounds 遮住边界 position 位置 shadowColor 阴影颜色 shadowOffset 阴影偏移 shadowOpacity 阴影透明度 shadowRadius 阴影半径
|
CAKeyframeAnimation 关键帧动画
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| CAKeyframeAnimation *keyFrameAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; keyFrameAnimation.duration = 2; keyFrameAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; 利用贝塞尔曲线绘制动画路径 UIBezierPath *path = [UIBezierPath bezierPath]; 曲线起点 [path moveToPoint:self.view.center]; 曲线轨迹(运动中将经过的点) [path addLineToPoint:CPM(MID_X, MID_Y + 200)]; [path addLineToPoint:CPM(MID_X + 100, MID_Y + 200)]; 闭合路径 [path addLineToPoint:CPM(MID_X + 100, MID_Y + 0)]; 设置动画的路径 keyFrameAnimation.path = path.CGPath; keyFrameAnimation.removedOnCompletion = NO; keyFrameAnimation.fillMode = kCAFillModeForwards; 配置关键帧的时间控制-按照比例分配每一段运动轨迹时间 keyFrameAnimation.keyTimes = @[@"0.0",@"0.5",@"0.75",@"1.0"];
[self.view.layer addAnimation:keyFrameAnimation forKey:@"position"];
|
CAAnimationGroup 动画组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 例:组合两个基础动画 动画1 CABasicAnimation *positionAnimation = [CABasicAnimation animationWithKeyPath:@"position"]; positionAnimation.fromValue = [NSValue valueWithCGPoint:self.view.center]; positionAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(CGRectGetMidX(self.view.bounds), 100)]; 动画2 CABasicAnimation *opacityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; opacityAnimation.fromValue = @(1.0); opacityAnimation.toValue = @(0.4); 动画组 CAAnimationGroup *group = [CAAnimationGroup animation]; group.animations = @[positionAnimation,opacityAnimation]; group.duration = 1; group.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; group.removedOnCompletion = NO; group.fillMode = kCAFillModeForwards; [self.view.layer addAnimation:group forKey:@"group"];
|
渐变色
1 2 3 4
| CAGradientLayer *gradientLayer = [CAGradientLayer layer]; gradientLayer.frame = self.view.bounds; gradientLayer.colors = @[(__bridge id)[UIColor colorWithRed:1.00 green:0.56 blue:0.00 alpha:1.00].CGColor,(__bridge id)[UIColor colorWithRed:0.26 green:0.79 blue:0.52 alpha:1.00].CGColor]; [self.view.layer addSublayer:gradientLayer];
|
设备存储路径
每一个App,iOS系统将会预设3个文件夹体感存储功能
1
| NSString *documentString = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
|
1
| NSString *libraryString = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)lastObject];
|
- tmp路径 - tmp作为临时存储,不向其中存储需要持久保留的数据
1
| NSString *tmpString = NSTemporaryDirectory();
|
把工程中的图片写入沙盒
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 1.保存图片的路径 NSString *documentString = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]; NSString *saveImagePath = [documentString stringByAppendingString:@“/图片名”]; 2.获取图片 NSString *path = [[NSBundle mainBundle]pathForResource:@“图片名” ofType:@“png”]; UIImage *image = [UIImage imageWithContentsOfFile:path]; 3.把图片转换为data NSData *imageData = UIImagePNGRepresentation(image); 4.写入沙盒 NSFileManager *manager = [NSFileManager defaultManager];//单例 if (![manager fileExistsAtPath:saveImagePath]) { [manager createFileAtPath:saveImagePath contents:imageData attributes:nil]; }
读取指定文件下的图片 [UIImage imageWithContentsOfFile:saveImagePath];
|
存储自定义对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| 例子:存储联系人信息数组
存储 1.获取联系人对象 Contact *acontact = [[Contact alloc]initWithDictionary:[self userDic]]; 2.获取保存文件路径 NSString *plistPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]; plistPath = [plistPath stringByAppendingString:@"/data.plist"]; 3.初始化写入沙盒的数组 NSMutableArray *dataList = [NSMutableArray array]; 4.归档(自动调用归档方法) NSData *data = [NSKeyedArchiver archivedDataWithRootObject:acontact]; 5.把归档所得数据添加的数组 [dataList addObject:data]; 6.将数组写入沙盒 BOOL success = [dataList writeToFile:plistPath atomically:YES]; NSLog(@"是否保存成功:%d",success);
读取 1.获取保存文件的路径 NSString *plistPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]; plistPath = [plistPath stringByAppendingString:@"/data.plist"]; 2.读取沙盒文件 NSArray *results = [NSArray arrayWithContentsOfFile:plistPath]; 3.解档 NSData *data = results[0];//取出data Contact *acontact = [NSKeyedUnarchiver unarchiveObjectWithData:data];
删除 1.获取保存文件的路径 NSString *plistPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]; plistPath = [plistPath stringByAppendingString:@"/data.plist"]; 2.清除 NSFileManager *manager = [NSFileManager defaultManager]; BOOL success = [manager removeItemAtPath:plistPath error:nil]; NSLog(@"是否清除成功:%d",success);
|
NSUserDefaults 存沙盒
1 2 3 4 5
| 存 [[NSUserDefaults standardUserDefaults] setObject:@[@"1"] forKey:@"mydata"]; [[NSUserDefaults standardUserDefaults] synchronize];//同步至沙盒 取 NSArray *array = [[NSUserDefaults standardUserDefaults] objectForKey:@"mydata"];
|
继承
面对对象的重要语法,OC只支持单继承
特点:
self
在类的方法中替代自身,替代调方法的角色,可以直接调用本类或父类的方法
super
在类的方法中替代父类,只能用来调用父类的方法,类中方法名与父类相同时,若想调用父类的方法时,只能使用super
多态
多态即为 接口的多种不同的实现方式,不同对象对同一消息的不同响应子类可以重写父类的方法,
多态允许方法重名,参数或返回值可以是父类型传入或返回
方法
-方法 调用 [对象 方法名]
+方法 调用 [类名 方法名]
setter,gettter 方法
1 2 3 4 5 6 7 8 9
| - (void)setName:(NSString *)name { _name = name; }
- (NSString *)name { retrun _name; }
|
重写description修改 %@ 的输出格式
集合类
集合类特点:
所有的集合都是对象
集合中所有的元素都是对象而且只能是对象
简单数据类型用NSNumber封装成对象,复杂数据类型用NSValue封装
集合中不能存放nil对象,nil是作为集合结束的标志符
OC集合没有多维的概念,不会出现根本意义上的二维数组
集合的所有运算依赖于方法
数组NSArray
c语言数据类型(int,float,double,BOOL)要封装成NSNumber类型后,才能存在集合中
NSArray 不可变数组
- 初始化
1 2 3 4 5 6
| [[NSArray alloc]initWithObject:@“1”,@“2”,@“3”,nil] [[NSArray alloc]initWithArray:array1]; [NSArray arrayWithObject:@“1”,@“2”,@“3”,nil] [NSArray arrayWithArray:array1]; 简化操作:NSArray = @[@“1”,@“2”,@“3”]; 标记static的数组,不能使用简写赋值
|
- 获取数组元素个数
1 2
| [array count]; array.count
|
- 添加元素
1 2
| [array arrayByAddingObject:@“4”]; [array arrayByAddingObjectFromArray:array1];
|
- 查找元素
1 2
| NSInteger index = [array indexObject:@“3”]; index == NSNotFound;
|
- 获取元素
1 2 3 4 5 6 7 8 9
| //存入的是什么类型,取出就用什么类型接受 array[0]; [array objectAtIndex:0]; //获取第一个元素 [array firstObject]; //获取最后一个元素 [array lastObject]; //获取部分元素 NSArray *getArray = [array subarrayWithRange”NSMakeRange(0,2)];
|
排序
快速枚举
1 2 3
| for(id obj in newArray){ NSLog(@“obj = %@”,obj); }
|
NSMutableArray 可变数组
- 初始化
基本同上,不能直接使用简化方法,
1 2
| NSMutableArray *array = [@[@“1”,@“2”]mutableCopy]; 额外一种, [NSMutableArray arrayWithCapacticy:20]; 分配容量
|
- 增
1
| [mutableArray addObject:@“0”];
|
- 删
1
| [mutableArray removeObject:@“2”];
|
- 查
1
| [mutableArray indexOfObject:@“0”]; 查出在数组中的位置
|
- 改
1
| [mutableArray replaceObjectAtIndex:2 withObject:@“0”]; 改数组中对应位置的元素
|
- 排序
字典NSDictionay
关键字及其定义的集合,字典也被称为 散列表或关联数组
- NSDictionay | value - key
1.初始化
一般初始化:NSDictionary *dictionary = [[NSDictionary alloc]initWithObjectsAndKeys:@“one”,@“1”,@“two”,@“2”,nil];
便利初始化: NSDictionary *dictionary = [NSDictionary dictionaryWithObjectAndKeys:@“one”,@“1”,@“two”,@“2”,nil];
快速初始化: NSDictionary *dictionary = @[@“1”:@“one”,@“2”:@“two”];
2.查询 [dictionary objectForKey:@“2”]; dictionary[@“2”];
3.取出所有key NSArray *key = [dictionary allKeys];
4.取出所有对象 NSArray *objects = [dictionary allValue];
初始化-基本同上
增
1
| [mutableDictionary setObject:@“six” forKey:@“6”];
|
- 删
1
| [mutableDictionary removeObjectForKey:@“6”];
|
- 查
1
| [mutableDictionary objectForKey:@“4”];
|
- 改(根据Key值覆盖之前的数据)
1
| [mutableDictionary setObject:@“sunny” forKey:@“4”];
|
- 遍历
1 2 3
| for(id key in mutableDictionary) { NSLog(@“%@”,[mutableDictionary objectForKey:Key]) }
|
里面的对象不能存放重复的对象,主要用于去除重复数,可用来清除其它集合中的重复对象
1 2 3 4 5
| 去除重复数 NSArray *array = @[@“1”,@“1”,@“2”,@“3”,@“3”,@“4”]; NSSet *set = [NSSet setWithArray:array]; NSArray *arraySet = [set allObject]; 得到的 arraySet 就是去除重复元素之后的数组
|
内存管理
内存管理的原理:
保证每个对象在使用时存在内存中,不用的对象最后从内存中清除一个对象的生命周期
对象初始化 -> 执行,使用 -> 释放内存管理只针对继承NSObject的对象,对C数据类型无效
retainCount引用计数
- 每个OC对象都有自己的引用计数器,retainCount
- 当对象被创建时,引用计数置为1
- retain使对象引用计数加1,并获得对象的所有权
- release使对象引用计数减1,并放弃对象的所有权
- 当引用计数为0时,对象将被系统销毁
1 2 3 4 5 6
| retainCount:获取对象当前的引用计数 alloc:返回一个对象,并将其引用计数设置为1,类方法 retain;将对象的引用计数加1 release:对象的引用计数减1 autoreplease:将对象加入自动释放池,对象引用计数滞后减1 dealloc,不主动调用,需要在类中重写
|
在非ARC模式下,进行内存管理
- 内存管理仅仅使用于对象类型,数据类型无需进行内存管理
- 使用alloc,new,copy,mutableCopy生成的对象,对象初始引用计数值为1,手动释放内存(堆)
- 使用便利初始化生成的对象,对象初始引用计数值为1,并且已经设置为自动释放(栈)
- 使用retain持有的对象,需要保证retain和release次数相等
setter,getter内存管理
1 2 3 4 5 6 7 8 9
| - (void)setName:(NSString *)name { if(name != name){ [name release]; //释放旧对象,持有新对象 _name = [name retain]; } } - (NSString *)name { retain _name; }
|
自定义初始化
自定义初始化方法中:
1 2 3
| if(self){ _name = [name retain]; }
|
集合内存管理:字典,数组
- 对象加入集合对象时,+1
- 对象从集合对象中移除,—1
- 集合对象的retainCount改变,其中元素的retainCount不变
- 集合对象销毁时,其中所有元素release一次
自动释放池NSAutoreleasePool
- 类似于一个容器,所有加入容器中的对象都可以被其管理,容器销毁时,池将会释放(release)所有对象
- 一个对象可以被多次autorelease
- 便利初始化的对象默认已经加入当前池中
1
| NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
|
单例模式
单例是生命周期与程序生命周期相同,仅能生成一次,且不能被销毁的唯一实例
单例设计模式要点
某个类只能有一个实例
必须自行创建这个对象
必须自行向整个系统提供这个实例
该方法必须是一个静态类
单例的创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| 当例一般以default,share,standard,getinstance开头 .h @property (nonatomic,strong) NSString *name;
//创建单例 //单例:以default,share,standard,getinstance开头 + (Singleton *)shareInstance;
.m //创建单例 + (Singleton *)shareInstance { if (!instance) { //(instance == nil)保证第一次创建成功后不再新建对象 instance = [[Singleton alloc]init]; } return instance; } //全套安全单例的创建,NSObject<NSCopying> + (instancetype)allocWithZone:(struct _NSZone *)zone { @synchronized(self) { 只能开辟一次空间 if (!instance) { instance = [super allocWithZone:zone]; } } return instance; }
- (id)copyWithZone:(NSZone *)zone { return self; }
- (instancetype)retain { return self; }
- (oneway void)release { }
- (instancetype)autorelease { return self; }
- (NSUInteger)retainCount { return NSUIntegerMax; }
GCD创建单例写法
|
观察者模式
事件响应
KVC
通过字符串描述来更改对象状态
存取通过属性或者直接设置实例变量来直接更改对象状态
-valueForKey -setValue:forKey
KVO
建立在KVC之上,能够观察一个对象KVC key path 值的变化
数据的持久化(数据存储) - NSUserDefaluts
1 2 3 4 5
| NSUserDefaluts *userDefaults = [NSUserDefaluts standardNSUserDefaluts]; 存数据: [userDefaults setObject:@“tom” forKey:@“name”]; 取数据: [userDefaults objectForKey:@“name”]; 删数据: [userDefaults removeObjectForKey:@“name”]; 更新数据同步文件 [userDefaults synchronize];
|
读写文件
可以通过代码,根据路径创建文件,来存储数据,这时数据不是存储在沙盒中
1 2
| 存:[array writeToFile:@“路径名/文件名.后缀名” atomically:YES]; 取: [NSArray arrayWithContentsOfFile:@“路径名/文件名.后缀名”];
|
属性
属性的声明
@property 关键字,声明一个属性
属性参数
1 2 3 4 5 6 7 8 9
| 内存管理相关 assign:缺省型,修饰基本数据类型和delegate对象,表示无需进行任何内存管理 retain:对象类型,持有对象,引用计数+1 copy:对象类型(NSCopying),持有对象,对象不可变复制 线程相关 atomic:关心线程安全,通常用于多线程,原子性 nonatomic:不关心线程安全,用于单线程,非原子性 读写/只读 readwrite:可读取,可改写 readonly:只读,提供getter方法,不提供setter方法 strong = retain | weak = assign
|
原子性:要么完整的被执行,要么完全不执行
属性的应用
用属性声明后就会自带setter,getter方法,可以直接使用点语法
copy关键字
当使用不可变类型的属性时,等同于strong,当使用可变类型时,每次赋值都会拷贝一个新的对象
深复制:内容复制,编译器会开辟新的内存来存储复制对象的数据,复制对象retaincount默认为1,需手动释放
浅赋值:指针赋值,只是将对象的引用计数加1,需要手动释放
copy:不可变复制,若对象时不可变的是浅复制,若对象时可变的是深复制,且复制对象不可变
mutableCopy:可变复制,无论对象可变还是不可变都是深复制,复制的对象可变