ios随记2
Posted joker4o
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ios随记2相关的知识,希望对你有一定的参考价值。
1,UIImage *image = [UIImage imageNamed:tempString];
这样看是图片内存会爆炸而且不会释放,图片多了出大事,图片少的并且重用多可以用性能会很高
NSString *path = [[NSBundle mainBundle] pathForResource:tempString
ofType:@“jpeg”];
UIImage *image = [UIImage imageWithContentsOfFile:path];
2.很多图片 先加到boundle里面性能好一点
mNzZG4ubmV0L2pva2VyNG8=,size_16,color_FFFFFF,t_70)
3,计时器实现
-(void)downSecondHandle:(NSString )aTimeString{
NSDateFormatter dateFormatter=[[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@“yyyy-MM-dd HH:mm:ss”];
NSDate endDate = [dateFormatter dateFromString:[self timeWithTimeIntervalString:aTimeString]]; //将秒数转化成时间得到的结束时间
//initwith将时间初始化为00,1,1+,timeIntervalSinceReferenceDate返回与00,1,1的秒数间隔
//NSDate endDate_tomorrow = [[NSDate alloc] initWithTimeIntervalSinceReferenceDate:([endDate timeIntervalSinceReferenceDate])];
NSDate startDate = [NSDate date];
NSString dateString = [dateFormatter stringFromDate:startDate];
NSLog(@“现在的时间 %@”,dateString);
//STimeInterval timeInterval =[endDate_tomorrow timeIntervalSinceDate: startDate];
NSTimeInterval timeInterval =[endDate timeIntervalSinceDate: startDate];
if (_timer==nil) {
//得到引用地址以方便修改数据
__block int timeout = timeInterval; //倒计时时间
if (timeout!=0) {
//GCD中的队列称为dispatchqueue,它可以保证先进来的任务先得到执行通过它能够大大简化多线程编程。工程师只要将要执行的任务(执行代码块)放入队列中,GCD将会为需要执行的任务创建thread,从而放入dispatch queue中,当将任务添加到队列立即安排开始执行。
dispatch_queue_t queue =
//dispatch_async函数会将传入的block块放入指定的queue里运行。这个函数是异步的,这就意味着它会立即返回而不管block是否运行结束。因此,我们可以在block里运行各种耗时的操作(如网络请求) 而同时不会阻塞UI线程。
//dispatch_get_global_queue 会获取一个全局队列,我们姑且理解为系统为我们开启的一些全局线程。我们用priority指定队列的优先级,而flag作为保留字段备用(一般为0)。
//dispatch_get_main_queue会返回主队列,也就是UI队列。它一般用于在其它队列中异步完成了一些工作后,需要在UI队列中更新界面(比如上面代码中的[selfupdateUIWithResult:result])的情况。
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//datapatch_source create 实现定时器
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
//设置参数
dispatch_source_set_timer(_timer,dispatch_walltime(NULL, 0),1.0NSEC_PER_SEC, 0); //每秒执行
dispatch_source_set_event_handler(_timer, ^{
if(timeout<=0){ //倒计时结束,关闭
dispatch_source_cancel(_timer);
_timer = nil;
dispatch_async(dispatch_get_main_queue(), ^{
self.dayLabel.text = @"";
self.hourLabel.text = @“00”;
self.minueLabel.text = @“00”;
self.secondLabel.text = @“00”;
});
}else{
NSLog(@“正在更新时间”);
int days = (int)(timeout/(360024));
if (days==0) {
self.dayLabel.text = @"";
}
int hours = (int)((timeout-days243600)/3600);
int minute = (int)(timeout-days243600-hours3600)/60;
int second = timeout-days243600-hours3600-minute*60;
dispatch_async(dispatch_get_main_queue(), ^{
if (days==0) {
self.dayLabel.text = @“0”;
}else{
self.dayLabel.text = [NSString stringWithFormat:@"%d",days];
}
if (hours<10) {
self.hourLabel.text = [NSString stringWithFormat:@“0%d”,hours];
}else{
self.hourLabel.text = [NSString stringWithFormat:@"%d",hours];
}
if (minute<10) {
self.minueLabel.text = [NSString stringWithFormat:@“0%d”,minute];
}else{
self.minueLabel.text = [NSString stringWithFormat:@"%d",minute];
}
if (second<10) {
self.secondLabel.text = [NSString stringWithFormat:@“0%d”,second];
}else{
self.secondLabel.text = [NSString stringWithFormat:@"%d",second];
}
});
timeout–;
}
});
//再次恢复计数
dispatch_resume(_timer);
}
}
}
4, 图片渐变可以用CAGradientLayer,设置从whiteColor到clearColor的渐变从而达到图片渐变
5,nil是表示0x0,可以理解为空指针。release是释放内存。
例如:你开辟了一块内存p= [[nsobject alloc] init]; 这个时候p是指向这块内存区域的,如果你直接p=nil,会造成这块内存没有被释放,内存泄露。 如果[p release]释放了内存,但是p还是指向这个内存地址,如果在操作p会出现EXC_BAD_ACCESS。正确的做法应该是释放后,把p指向nil
nil、Nil、NULL的区别
nil:指向oc中对象的空指针,针对对象。
Nil:指向oc中类的空指针,针对类。
NULL:指向其他类型的空指针,如一个c类型的内存指针,基本数据类型为空,基本类型。
NSNull:在集合对象中,表示空值的对象。
若obj为nil
[obj message]将返回NO,而不是NSException
若obj为NSNull
[obj message]将抛出异常NSException
6,tabview刷新数据紊乱;tabview会重用cell,而cell是当一个cell消失在屏幕外就会被回收,当回到屏幕就会重新去chon如果你采用了static NSString* cellID = @“cellID”;这样的方式定义cell,
7,property方法系统自动生成了set与get方法,而且会以_下划线的形式把数据存到地址里面,所以只要有一个人修改了地址里面的值,其他的都会知道。
8,xcode12,如果有网络图片,或者网络数据加载不了报错,安全配置什么的,其实不需要,只要把数据的URL 把http变成https就行了,这样就不会阻拦了
9,__block就是拿到变量真实地址,在block中操作就可以直接更改变量的值,不然拿到的就是瞬时值
10 横屏优先级的问题,general == appDelegate >> rootViewController >> nomalViewController,高级的开了不能旋转,低级的怎么开都没有用
可能造成tableView卡顿的原因有:
1.最常用的就是cell的重用, 注册重用标识符
如果不重用cell时,每当一个cell显示到屏幕上时,就会重新创建一个新的cell
如果有很多数据的时候,就会堆积很多cell。
如果重用cell,为cell创建一个ID,每当需要显示cell 的时候,都会先去缓冲池中寻找可循环利用的cell,如果没有再重新创建cell
2.避免cell的重新布局
cell的布局填充等操作 比较耗时,一般创建时就布局好
如可以将cell单独放到一个自定义类,初始化时就布局好
3.提前计算并缓存cell的属性及内容
当我们创建cell的数据源方法时,编译器并不是先创建cell 再定cell的高度
而是先根据内容一次确定每一个cell的高度,高度确定后,再创建要显示的cell,滚动时,每当cell进入凭虚都会计算高度,提前估算高度告诉编译器,编译器知道高度后,紧接着就会创建cell,这时再调用高度的具体计算方法,这样可以方式浪费时间去计算显示以外的cell
4.减少cell中控件的数量
尽量使cell得布局大致相同,不同风格的cell可以使用不用的重用标识符,初始化时添加控件,
不适用的可以先隐藏
5.不要使用ClearColor,无背景色,透明度也不要设置为0
渲染耗时比较长
6.使用局部更新
如果只是更新某组的话,使用reloadSection进行局部更
7.加载网络数据,下载图片,使用异步加载,并缓存
8.少使用addView 给cell动态添加view
9.按需加载cell,cell滚动很快时,只加载范围内的cell
10.不要实现无用的代理方法,tableView只遵守两个协议
11.缓存行高:estimatedHeightForRow不能和HeightForRow里面的layoutIfNeed同时存在,这两者同时存在才会出现“窜动”的bug。所以我的建议是:只要是固定行高就写预估行高来减少行高调用次数提升性能。如果是动态行高就不要写预估方法了,用一个行高的缓存字典来减少代码的调用次数即可
12.不要做多余的绘制工作。在实现drawRect:的时候,它的rect参数就是需要绘制的区域,这个区域之外的不需要进行绘制。例如上例中,就可以用CGRectIntersectsRect、CGRectIntersection或CGRectContainsRect判断是否需要绘制image和text,然后再调用绘制方法。
13.预渲染图像。当新的图像出现时,仍然会有短暂的停顿现象。解决的办法就是在bitmap context里先将其画一遍,导出成UIImage对象,然后再绘制到屏幕;
14.使用正确的数据结构来存储数据。
15 可变数组与NSStringcopy深浅
copy对NSArray进行的是浅拷贝。
mutableCopy对NSArray进行的是深拷贝,且拷贝之后数组变成了一个可变数组。
copy对NSMutableArray进行的是深拷贝,拷贝之后的新数组是一个不可变数组。
mutableCopy对NSMutableArray进行的是深拷贝,且拷贝之后是一个新的可变数组。
静态字符串,无论是使用strong还是copy修饰,字符串之间的修改的都是独立的,不会互相影响。
strong修饰的self.firstName两次的打印值是不一样的,第二次打印值和orgMstr是一样的,对orgMstr的修改,竟然影响了self.firstName的值,产生了我们不想要的结果(意外值串改)。这在开发中会导致预想不到的bug,排查困难。
而使用copy修饰的self.secondName两次的打印值是一样的,就是说orgMStr和self.secondName的修改是独立的,不会互相影响,这才是开发真正需要的效果。
以上是关于ios随记2的主要内容,如果未能解决你的问题,请参考以下文章