ios面试技巧宝典(共7篇)
篇1:ios面试技巧宝典
数据存储(★★)
1、IOS中常用的数据存储方式有哪些?
答:1.数据存储有四种方案,NSUserDefault,KeyChain,File,DB.2.其中File有三种方式:plist,Archiver,Stream 3.DB包括core Data和FMDB
2、说一说你对sqlite的认识
SQLite是目前主流的嵌入式关系型数据库,其最主要的特点就是轻量级、跨平台,当前很多嵌入式操作系统都将其作为数据库首选。虽然SQLite是一款轻型数据库,但是其功能也绝不亚于很多大型关系数据库。学习数据库就要学习其相关的定义、操作、查询语言,也就是大家日常说得SQL语句。和其他数据库相比,SQLite中的SQL语法并没有太大的差别,因此这里对于SQL语句的内容不会过多赘述,大家可以参考SQLite中其他SQL相关的内容,这里还是重点讲解iOS中如何使用SQLite构建应用程序。先看一下SQLite数据库的几个特点:
1.基于C语言开发的轻型数据库
2.在iOS中需要使用C语言语法进行数据库操作、访问(无法使用ObjC直接访问,因为libqlite3框架基于C语言编写)
3.SQLite中采用的是动态数据类型,即使创建时定义了一种类型,在实际操作时也可以存储其他类型,但是推荐建库时使用合适的类型(特别是应用需要考虑跨平台的情况时)
4.建立连接后通常不需要关闭连接(尽管可以手动关闭)
在iOS中操作SQLite数据库可以分为以下几步(注意先在项目中导入libsqlite3框架):
1.打开数据库,利用sqlite3_open()打开数据库会指定一个数据库文件保存路径,如果文件存在则直接打开,否则创建并打开。打开数据库会得到一个sqlite3类型的对象,后面需要借助这个对象进行其他操作。
2.执行SQL语句,执行SQL语句又包括有返回值的语句和无返回值语句。3.对于无返回值的语句(如增加、删除、修改等)直接通过sqlite3_exec()函数执行;
4.对于有返回值的语句则首先通过sqlite3_prepare_v2()进行sql语句评估(语法检测),然后通过sqlite3_step()依次取出查询结果的每一行数据,对于每行数据都可以通过对应的sqlite3_column_类型()方法获得对应列的数据,如此反复循环直到遍历完成。当然,最后需要释放句柄。
3、说一说你对FMDB的认识
FMDB是一个处理数据存储的第三方框架,框架是对sqlite的封装,整个框架非常轻量级但又不失灵活性,而且更加面向对象。FMDB有如下几个特性:
1.FMDB既然是对于libsqlite3框架的封装,自然使用起来也是类似的,使用前也要打开一个数据库,这个数据库文件存在则直接打开否则会创建并打开。这里FMDB引入了一个MFDatabase对象来表示数据库,打开数据库和后面的数据库操作全部依
赖此对象。
2.对于数据库的操作跟前面KCDbManager的封装是类似的,在FMDB中FMDatabase类提供了两个方法executeUpdate:和executeQuery:分别用于执行无返回结果的查询和有返回结果的查询。当然这两个方法有很多的重载这里就不详细解释了。唯一需要指出的是,如果调用有格式化参数的sql语句时,格式化符号使用“?”而不是“%@”、等。
3.我们知道直接使用libsqlite3进行数据库操作其实是线程不安全的,如果遇到多个线程同时操作一个表的时候可能会发生意想不到的结果。为了解决这个问题建议在多线程中使用FMDatabaseQueue对象,相比FMDatabase而言,它是线程安全的。
4.将事务放到FMDB中去说并不是因为只有FMDB才支持事务,而是因为FMDB将其封装成了几个方法来调用,不用自己写对应的sql而已。其实在在使用libsqlite3操作数据库时也是原生支持事务的(因为这里的事务是基于数据库的,FMDB还是使用的SQLite数据库),只要在执行sql语句前加上“begin transaction;”执行完之后执行“commit transaction;”或者“rollback transaction;”进行提交或回滚即可。另外在Core Data中大家也可以发现,所有的增、删、改操作之后必须调用上下文的保存方法,其实本身就提供了事务的支持,只要不调用保存方法,之前所有的操作是不会提交的。在FMDB中FMDatabase有beginTransaction、commit、rollback三个方法进行开启事务、提交事务和回滚事务。
4、说一说你对Core Data的认识
Core Data使用起来相对直接使用SQLite3的API而言更加的面向对象,操作过
程通常分为以下几个步骤:
1.创建管理上下文
创建管理上下可以细分为:加载模型文件->指定数据存储路径->创建对应数据类型的存储->创建管理对象上下方并指定存储。
经过这几个步骤之后可以得到管理对象上下文NSManagedObjectContext,以后所有的数据操作都由此对象负责。同时如果是第一次创建上下文,Core Data会自动创建存储文件(例如这里使用SQLite3存储),并且根据模型对象创建对应的表结构。
2.查询数据
对于有条件的查询,在Core Data中是通过谓词来实现的。首先创建一个请求,然后设置请求条件,最后调用上下文执行请求的方法。
3.插入数据
插入数据需要调用实体描述对象NSEntityDescription返回一个实体对象,然后设置对象属性,最后保存当前上下文即可。这里需要注意,增、删、改操作完最后必须调用管理对象上下文的保存方法,否则操作不会执行。
4.删除数据
删除数据可以直接调用管理对象上下文的deleteObject方法,删除完保存上下文即可。注意,删除数据前必须先查询到对应对象。
5.修改数据
修改数据首先也是取出对应的实体对象,然后通过修改对象的属性,最后保存上下文。
5、OC中有哪些数据存储方式,各有什么区别? OC中有四种数据存储方式: 1).NSUserDefaults,用于存储配置信息 2).SQLite,用于存储查询需求较多的数据 3).CoreData,用于规划应用中的对象
4).使用基本对象类型定制的个性化缓存方案.NSUserDefaults:对象中储存了系统中用户的配置信息,开发者可以通过这个实例对象对这些已有的信息进行修改,也可以按照自己的需求创建新的配置项。SQLite擅长处理的数据类型其实与NSUserDefaults差不多,也是基础类型的小数据,只是从组织形式上不同。开发者可以以关系型数据库的方式组织数据,使用SQL DML来管理数据。一般来说应用中的格式化的文本类数据可以存放在数据库中,尤其是类似聊天记录、Timeline等这些具有条件查询和排序需求的数据。CoreData是一个管理方案,它的持久化可以通过SQLite、XML或二进制文件储存。它可以把整个应用中的对象建模并进行自动化的管理。从归档文件还原模型时CoreData并不是一次性把整个模型中的所有数据都载入内存,而是根据运行时状态,把被调用到的对象实例载入内存。框架会自动控制这个过程,从而达到控制内存消耗,避免浪费。无论从设计原理还是使用方法上看,CoreData都比较复杂。因此,如果仅仅是考虑缓存数据这个需求,CoreData绝对不是一个优选方案。CoreData的使用场景在于:整个应用使用CoreData规划,把应用内的数据通过CoreData建模,完全基于CoreData架构应用。使用基本对象类型定制的个性化缓存方案:从需求出发分析缓存数据有哪些要求:按Key查找,快速读取,写入不影响正常操作,不浪费内存,支持归档。这些都是基本需求,那么再进一步或许还需要固定缓存项数量,支持队列缓存,缓存过期等。
数据存储这一块,面试常问, 你常用哪一种数据存储?什么是序列化?sqlite是直接用它还是用封装了它的第三方库?尤其是会问sqlite和core data的区别?
5、IOS平台怎么做数据的持久化?coredata和sqlite有无必然联系?coredata是一个关系型数据库吗?
iOS中可以有四种持久化数据的方式: 属性列表、对象归档、SQLite3和Core Data coredata可以使你以图形界面的方式快速的定义app的数据模型,同时在你的代码中容易获取到它。coredata提供了基础结构去处理常用的功能,例如保存,恢复,撤销和重做,允许你在app中继续创建新的任务。在使用coredata的时候,你不用安装额外的数据库系统,因为coredata使用内置的sqlite数据库。coredata将你app的模型层放入到一组定义在内存中的数据对象。coredata会追踪这些对象的改变,同时可以根据需要做相应的改变,例如用户执行撤销命令。当coredata在对你app数据的改变进行保存的时候,core data会把这些数据归档,并永久性保存。mac os x中sqlite库,它是一个轻量级功能强大的关系数据引擎,也很容易嵌入到应用程序。可以在多个平台使用,sqlite是一个轻量级的嵌入式sql数据库编程。与coredata框架不同的是,sqlite是使用程序式的,sql的主要的API来直接操作数据表。Core Data不是一个关系型数据库,也不是关系型数据库管理系统(RDBMS)。虽然Core Dta支持SQLite作为一种存储类型, 但它不能使用任意的SQLite数据库。Core Data在使用的过程种自己创建这个数据库。Core Data支持对
一、对多的关系。
6、如果后期需要增加数据库中的字段怎么实现,如果不使用CoreData呢?
编写SQL语句来操作原来表中的字段 增加表字段
ALTER TABLE 表名 ADD COLUMN 字段名字段类型;• 删除表字段
ALTER TABLE 表名 DROP COLUMN 字段名;
.修改表字段
ALTER TABLE 表名 RENAME COLUMN 旧字段名 TO 新字段名;
7、SQLite数据存储是怎么用?
添加SQLite动态库:
导入主头文件:#import
8、简单描述下客户端的缓存机制?
1>缓存可以分为:内存数据缓存、数据库缓存、文件缓存 2>每次想获取数据的时候 3>先检测内存中有无缓存
4>再检测本地有无缓存(数据库文件)5>最终发送网络请求
6>将服务器返回的网络数据进行缓存(内存、数据库、文件),以便下次读取
9、你实现过多线程的Core Data么?NSPersistentStoreCoordinator,NSManagedObjectContext和NSManagedObject中的哪些需要在线程中创建或者传递?你是用什么样的策略来实现的?
1>CoreData是对SQLite数据库的封装
2>CoreData中的NSManagedObjectContext在多线程中不安全
3>如果想要多线程访问CoreData的话,最好的方法是一个线程一个NSManagedObjectContext 4>每个NSManagedObjectContext对象实例都可以使用同一个NSPersistentStoreCoordinator实例,这是因为NSManagedObjectContext会在便用NSPersistentStoreCoordinator前上锁
10、core data数据迁移
博客地址: http://blog.csdn.net/jasonblog/article/details/17842535
11、FMDB的使用和对多张表的处理
博客地址: http://blog.csdn.net/wscqqlucy/article/details/8464398
12、说说数据库的左连接和右连接的区别
数据库左连接和右连接的区别:主表不一样通过左连接和右连接,最小条数为3(记录条数较小的记录数),最大条数为12(3×4)技术博客的地址 : http://
篇2:ios面试技巧宝典
1.谈谈你对Core Graphic 绘图的了解? CoreGraphics也称为Quartz 2D 是UIKit下的主要绘图系统,频繁的用于绘制自定义视图。Core Graphics是高度集成于UIView和其他UIKit部分的。Core Graphics数据结构和函数可以通过前缀CG来识别。
视图可以通过子视图、图层或实现drawRect:方法来表现内容,如果说实现了drawRect:方法,那么最好就不要混用其他方法了,如图层和子视图。自定义绘图大部分是由UIKit或者Core Graphics来实现的。
2D绘图一般可以拆分成以下几个操作: 线条 , 路径 , 文本 , 图片 , 渐变 由于像素是依赖于目标的,所以2D绘图并不能操作单独的像素,我们可以从上下文(Context)读取它。
绘图就好比在画布上拿着画笔机械的进行画画,通过制定不同的参数来进行不同的绘制。
http:///articles/jIJzMf
http://blog.csdn.net/mangosnow/article/details/37054765
2.Core Animation(核心动画)? CoreAnimation也就是核心动画, 是一组非常强大的动画处理API, 可以使用少量的代码做出绚丽的效果, 是直接作用在CALayer上的, 并非UIView, 并且Core Animation的动画执行过程都是在后台操作, 不会阻塞主线程.所有动画都是作用在CALayer上的, 当把动画添加到Layer上, 是不直接修改它的属性, Core Animation维护了两个平行layer的层次结构, 模型层树可以看到Layer的状态, 表示层树则是动画正在表现的值的近似.Core Animation的使用步骤: 1> 使用它需要先添加QuartzCore.framework框架和引入主头文件
3>.通过调用CALayer的addAnimation:forKey:方法增加CAAnimation对象到CALayer中,这样就能开始执行动画了
4>.通过调用CALayer的removeAnimationForKey:方法可以停止CALayer中的动画
1.转场动画? CATransition-转场动画, 作为CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。iOS比Mac OS X的转场动画效果少一点.UINavigationController就是通过CATransition实现了将控制器的视图推入屏幕的动画效果.如下是转场动画的过渡效果:
使用UIView的动画函数, 实现转场动画 1> 单视图:
+(void)transitionWithView:(UIView*)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options
animations:(void(^)(void))animations completion:(void(^)(BOOL finished))completion;参数说明:
duration:动画的持续时间 view:需要进行转场动画的视图 options:转场动画的类型
animations:将改变视图属性的代码放在这个block中 completion:动画结束后,会自动调用这个block 2> 双视图: +(void)transitionFromView:(UIView*)fromView toView:(UIView*)toView
duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options finished))completion;参数说明:
duration:动画的持续时间 options:转场动画的类型
animations:将改变视图属性的代码放在这个block中 completion:动画结束后,会自动调用这个block
completion:(void
(^)(BOOL 2.一个动画怎么实现? 以转场动画为例: 1> 创建CATransition对象
CATransition *animation = [CATransition animation];2> 设置运动时间(即动画时间)animation.duration = DURATION;3> 设置运动type(类型)
animation.type = type;if(subtype!= nil){ 4> 设置子类(和type配合使用, 指定运动的方向)animation.subtype = subtype;} 5> 设置运动速度(动画的运动轨迹,用于变化起点和终点之间的插值计算,形象点说它决定了动画运行的节奏,比如是均匀变化(相同时间变化量相同)还是先快后慢,先慢后快还是先慢再快再慢)animation.timingFunction = UIViewAnimationOptionCurveEaseInOut;
6> 将动画添加到view的Layer层
[view.layer addAnimation:animation forKey:@“animation”];动画类型如下: typedef enum : NSUInteger { Fade = 1, //淡入淡出 Push, //推挤 Reveal, //揭开 MoveIn, //覆盖 Cube, //立方体 SuckEffect, //吮吸 OglFlip, //翻转 RippleEffect, //波纹
PageCurl, //翻页 PageUnCurl, //反翻页 CameraIrisHollowOpen, //开镜头 CameraIrisHollowClose, //关镜头 CurlDown, //下翻页 CurlUp, //上翻页 FlipFromLeft, //左翻转 FlipFromRight, //右翻转 } AnimationType;3.CADisplayLink CADisplayLink是一种以屏幕刷新频率触发的时钟机制,每秒钟执行大约60次左右
CADisplayLink是一个计时器,可以使绘图代码与视图的刷新频率保持同步,而NSTimer无法确保计时器实际被触发的准确时间 使用方法:
篇3:iOS 7节能技巧
因而,要让iOS 7更节能,只需将各种我们不需要的功能关闭,特别是对于动态效果、定位、推送等对能耗影响较大的功能进行设置调整,就完全可以使手机的续航时间恢复到此前版本的水平。
节能技巧
减少动态效果 首先,我们可以打开“设置|通用|辅助功能|减少动态效果”选项,减少不必要的动态效果。
减少推送数据 要避免不必要的推送数据增加功耗,可以通过“设置|邮件、通讯录、日历|获取新数据”关闭邮件推送数据,或者通过“获取”设置降低推送的频率。其次,可以通过“设置|通知中心”关闭通知中心不必要的应用推送。
减少后台应用的影响 按两下“Home”键,将不必要的应用预览图标向上推出屏幕即可关闭不必要的后台应用。对于希望保留的应用,可以通过“设置|通用|后台应用程序刷新”控制指定的应用是否刷新数据,以及通过“设置|隐私|定位服务”关闭定位服务,或者指定允许使用定位服务的应用。
关闭AirDrop 不需要AirDrop功能的用户可以从屏幕底部向上滑动打开控制中心,点击AirDrop,选择“停用”关闭AirDrop功能。
停用Siri Siri虽然是iOS中很受注目的一项功能,但同样也有许多用户基本不使用它,确实不使用的用户可以通过“设置|通用|Siri”关闭该功能。
设置屏幕亮度 屏幕是最耗电的零部件,因而如果希望节省更多电量,则可以通过“设置|墙纸与亮度”关闭“自动亮度调节”,并设置一个偏低的屏幕亮度即可。
篇4:ios面试技巧宝典
2.向下拖动tableView,当cell1完全移出屏幕,并且 cell11(它也是alloc出来的,原因同上)完全显示出来的时候。cell11加入到visiableCells,cell1移出 visiableCells,cell1加入到reusableTableCells。
3.接着向下拖动tableView,因为reusableTableCells中已 经有值,所以,当需要显示新的cell, cellForRowAtIndexPath再次被调用的时 候,tableView dequeueReusableCellWithIdentifier:CellIdentifier,返回cell1。cell1加入到visiableCells,cell1 移出reusableTableCells;cell2移出 visiableCells,cell2加入到reusableTableCells。之后再需要显示的Cell就可 以正常重用了
2.在一个tableView 中需要自定义多种样式的cell(两种或三种),通常你如何实现,说说思路即可? 比如:有100条数据,iPhone一屏最多显示10个cell。程序最开始显示TableView的情况是: 1.用[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] 创建10次cell,并给cell指定同样的重用标识(当然,可以为不同显示类型的cell指定不同的标识)。并且10个cell全部都加 入到 visiableCells数组,reusableTableCells为空。
2.向下拖动tableView,当cell1完全移出屏幕,并且 cell11(它也是alloc出来的,原因同上)完全显示出来的时候。cell11加入到visiableCells,cell1移出 visiableCells,cell1加入到reusableTableCells。
3.接着向下拖动tableView,因为reusableTableCells中已 经有值,所以,当需要显示新的cell, cellForRowAtIndexPath再次被调用的时 候,tableView dequeueReusableCellWithIdentifier:CellIdentifier,返回cell1。cell1加入到visiableCells,cell1 移出reusableTableCells;cell2移出 visiableCells,cell2加入到
reusableTableCells。之后再需要显示的Cell就可 以正常重用了
3.UITableView的性能优化? 滑动的时候有种卡的感觉是为什么?怎么解决?
然而在使用第三方应用时,却经常遇到性能上的问题,普遍表现在滚动时比较卡,特别是table cell中包含图片的情况时。实际上针对性地优化一下就可以解决tableView滑动的时候卡顿的问题, 在iOS应用中,UITableView应该是使用率最高的视图之一了。iPod、时钟、日历、备忘录、Mail、天气、照片、电话、短信、Safari、App Store、iTunes、Game Center⋯几乎所有自带的应用中都能看到它的身影,可见它的重要性。然而在使用第三方应用时,却经常遇到性能上的问题,普遍表现在滚动时比较卡,特别是table cell中包含图片的情况时。
实际上只要针对性地优化一下: 1>同一时间其实只需要存在一屏幕的cell对象即可,不需要为每一行创建一个cell。
UITableView是UIScrollView的子类,因此它可以自动响应滚动事件(一般为上下滚动)。它内部包含0到多个UITableViewCell对象,每个table cell展示各自的内容。当新cell需要被显示时,就会调用tableView:cellForRowAtIndexPath:方法来获取或创建一个 cell;而不可视时,它又会被释放。由此可见,同一时间其实只需要存在一屏幕的cell对象即可,不需要为每一行创建一个cell。此 外,UITableView还可以分为多个sections,每个区段都可以有自己的head、foot和cells。而在定位一个cell时,就需要2 个字段了:在哪个section,以及在这个section的第几行。这在iOS SDK中是用NSIndexPath来表述的,UIKit为其添加了indexPathForRow:inSection:这个创建方法。其他诸如编辑之类的就不提了,因为和本文无关。
介绍完原理,接下来就开始优化吧。
使用不透明视图。
不透明的视图可以极大地提高渲染的速度。因此如非必要,可以将table cell及其子视图的opaque属性设为YES(默认值)。其中的特例包括背景色,它的alpha值应该为1(例如不要使用clearColor);图像的alpha值也应该为1,或者在画图时设为不透明。
不要重复创建不必要的table cell。
前面说了,UITableView只需要一屏幕的UITableViewCell对象即可。因此在cell不可见时,可以将其缓存起来,而在需要时继续使用它即可。而UITableView也提供了这种机制,只需要简单地设置一个identifier即可:
static NSString *CellIdentifier = @“xxx”;UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];if(cell == nil){ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];} 值得一提的是,cell被重用时,它内部绘制的内容并不会被自动清除,因此你可能需要调用setNeedsDisplayInRect:或setNeedsDisplay方法。此 外,在添加table cell的时候,如果不需要动画效果,最好不要使用insertRowsAtIndexPaths:withRowAnimation:方法,而是直接调 用reloadData方法。因为前者会对所有indexPaths调用tableView:cellForRowAtIndexPath:方法,即便该 cell并不需要显示(不知道是不是bug),这就可能创建大量多余的cell。勘误:只是在模拟器上测试如此,真机调试时没有这种bug。
减少视图的数目。
UITableViewCell包含了textLabel、detailTextLabel和imageView等view,而
你还可以自定义一些视图放在它的contentView里。然而view是很大的对象,创建它会消耗较多资源,并且也影响渲染的性能。如果你的table cell包含图片,且数目较多,使用默认的UITableViewCell会非常影响性能。奇怪的是,使用自定义的view,而非预定义的view,明显会快些。当然,最佳的解决办法还是继承UITableViewCell,并在其drawRect:中自行绘制:
-(void)drawRect:(CGRect)rect { if(image){ [image drawAtPoint:imagePoint];self.image = nil;} else { [placeHolder drawAtPoint:imagePoint];} [text drawInRect:textRect withFont:font lineBreakMode:UILineBreakModeTailTruncation];} 不过这样一来,你会发现选中一行后,这个cell就变蓝了,其中的内容就被挡住了。最简单的方法就是将cell的selectionStyle属性设为UITableViewCellSelectionStyleNone,这样就不会被高亮了。此外还可以创建CALayer,将内容绘制到layer上,然后对cell的contentView.layer调用addSublayer:方法。这个例 子中,layer并不会显著影响性能,但如果layer透明,或者有圆角、变形等效果,就会影响到绘制速度了。解决办法可参见后面的预渲染图像。
不要做多余的绘制工作。
在实现drawRect:的时候,它的rect参数就是需要绘制的区域,这个区域之外的不需要进行绘制。例如上例中,就可以用CGRectIntersectsRect、CGRectIntersection或CGRectContainsRect判断是否需要绘制image和text,然后再调用绘制方法。
预渲染图像。
你会发现即使做到了上述几点,当新的图像出现时,仍然会有短暂的停顿现象。解决的办法就是在bitmap context里先将其画一遍,导出成UIImage对象,然后再绘制到
屏幕,详细做法可见《利用预渲染加速iOS设备的图像显示》。
不要阻塞主线程。
做到前几点后,你的table view滚动时应该足够流畅了,不过你仍可能让用户感到不爽。常见的现象就是在更新数据时,整个界面卡住不动,完全不响应用户请求。出现这种现象的原因就是主线程执行了耗时很长的函数或方法,在其执行完毕前,无法绘制屏幕和响应用户请求。其中最常见的就是网络请求了,它通常都需要花费数秒的时间,而你不应该让用户等待那么久。解决办法就是使用多线程,让子线程去执行这些函数或方法。这里面还有一个学问,当下载线程数超过2时,会显著影响主线程的性能。因此在使用 ASIHTTPRequest时,可以用一个NSOperationQueue
来维护下载请求,并将其
maxConcurrentOperationCount设为2。而NSURLRequest则可以配合GCD来实现,或者使用NSURLConnection的setDelegateQueue:方法。当然,在不需要响应用户请求时,也可以增加下载线程数,以加快下载速度:
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { if(!decelerate){ queue.maxConcurrentOperationCount = 5;} }(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { queue.maxConcurrentOperationCount = 2;} 此外,自动载入更新数据对用户来说也很友好,这减少了用户等待下载的时间。例如每次载入50条信息,那就可以在滚动到倒数第10条以内时,加载更多信息:
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { if(count-indexPath.row < 10 &&!updating){ updating = YES;[self update];} }// update方法获取到结果后,设置updating为NO 还有一点要注意的就是当图片下载完
成后,如果cell是可见的,还需要更新图像:
NSArray *indexPaths = [self.tableView indexPathsForVisibleRows];for(NSIndexPath *visibleIndexPath in indexPaths){ if(indexPath == visibleIndexPath){ MyTableViewCell *cell =(MyTableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath];cell.image = image;[cell setNeedsDisplayInRect:imageRect];break;} }// 也可不遍历,直接与头尾相比较,看是否在中间即可。最后还是前面所说过的insertRowsAtIndexPaths:withRowAnimation:方法,插入新行需要在主线程执行,而一次插入很多行的话(例如50行),会长时间阻塞主线程。而换成reloadData方法的话,瞬间就处理完了。l 4 tableview的cell里如何嵌套collection view?
思路同网易新闻类似, 用自定义的继承自UITableViewCell的类, 在initWithFrame的构造方法中, 初始化自定义的继承自UICollectionView的类 下拉和上拉的原理? 上拉和下拉的原理可以参照新浪微博的上拉和下拉刷新, 以tableView的上拉刷新为例:
1> 为了进行无缝阅读, 通过tableView的代理方法, willDisplayCell判断是否是最后一行,2> 如果是最后一行, 在显示最后一行的同时, 判断当前是否存在上拉刷新 3> 如果当前没有上拉刷新, 就进行加载数据, 启动”橘花”
以tableView的下拉刷新为例: 1> 判断当前的上拉刷新视图是否动画
篇5:ios基础面试题
1、Object-C有多继承吗?没有的话用什么代替?
2、Object-C有私有方法吗?私有变量呢?
3、关键字const什么含义?
4、关键字volatile有什么含义?并给出三个不同例子?
5、static作用?
6、#import和#include的区别,@class代表什么?
7、线程和进程的区别?
8、堆和栈的区别?
9、Object-C的内存管理?
10、为什么很多内置的类,如TableViewController的delegate的属性是assign不是retain?
11、定义属性时,什么情况使用copy、assign、retain?
12、对象是什么时候被release的?
13、iOS有没有垃圾回收?
14、tableView的重用机制?
15、ViewController 的loadView、viewDidLoad、viewDidUnload分别是什么时候调用的,在自定义ViewCointroller时在这几个函数中应该做什么工作?
16、ViewController的didReceiveMemoryWarning是在什么时候调用的?默认的操作是什么?
17、列举Cocoa中常见的集中多线程的实现,并谈谈多线程安全的几种解决办法,一般什么地方会用到多线程?
18、怎么理解MVC,在Cocoa中MVC是怎么实现的?
19、delegate和notification区别,分别在什么情况下使用?
20、self.跟self什么区别?
21、id、nil代表什么?
22、内存管理 Autorelease、retain、copy、assign的set方法和含义?
23、类别的作用?
24、委托(举例)
25、retainCount?
更多经典的面试试题分享:
iPhone软件开发面试题
九种最难缠的面试题
银行面试常见问题
篇6:腾讯公司ios面试题
2。viewcontroller的一些方法的说明viewDidLoad, viewWillDisappear, viewWillAppear方法的 顺序和 作用?
3。frame 和 bounds 的 区别 ,bound的大小改变frame 改变吗?
4。sqlite中插入特殊字符的方法和接收到处理方法。
5。谈谈你对数组和连表认识,还有你是怎么用他们的?
6。冒泡算法。
7。socket编程简述
8。asihttp代码原理 ,异步请求的原理,异步请求最大数目,为什么只能这么多?
9。http请求方式?
10。uiview的圆角属性设置方法。
(m_mainImgView.layer.cornerRadius = 6;
m_mainImgView.layer.masksToBounds = YES;)
11。 masksToBounds属性的作用。(决定子layer是否被当前layer的边界剪切。默认是NO。)
篇7:iOS下的iPhoto小技巧
要完成照片矫正工作,iOS下的iPhoto有不少聪明的做法。第一个是自动检测水平线。打开iPhoto,选择一个准备编辑的照片,然后点“Edit(编辑)”。再点击底部左侧的“Crop & Straighten(剪切&矫正)”图标。如果照片上显示出了一条横贯左右的白线,则表明水平线自动检测成功。要完成矫正,只需简单的点击照片右侧的箭头图标即可。
不幸的是,iPhoto并不见得每次都能找出水平线,这时候就该你自己亲自动手调整了。“Crop & Straighten”模式会在你的图片下方放置一个刻度盘,你可以通过将刻度盘朝左右拖动,来对照片进行矫正。在旋转刻度盘时,照片上会出现相应的网格,让你矫正的时候有个参照。
那么,如果照片上没有很明显的参照物时又该咋办呢?iPhoto还有其他的办法,而且这方法用起来还颇有乐趣。选择一张打算矫正的照片,然后将你的iPhone(或iPAD)举到自己面前。现在,点击刻度盘。iPhoto会调用设备中的陀螺仪来协助矫正图片。你可以简单的朝左或者朝右倾斜你的iPhone(iPAD),可以看到,照片始终保持竖直。如果你在倾斜设备的同时倾斜脑袋,这一点就会很有用处,有助于你对照片做出更好的剪裁。一旦你对照片的调整感到满意了,点击屏幕上任意位置,即可锁定该照片。
图一iPhoto通常都能检测出地平线;此时如果要矫正照片,直接点击右侧的箭头图标即可。
特效应用和调整
和台式机中的伙伴相比,iOS下iPhoto的特效更多。打开iPhoto,选中一张照片,然后点击“Edit(编辑)”。现在,点击左下角的“Effects(特效)”图标,一个可用的特效列表就会弹出来。其中有两套效果令人印象颇为深刻,一个是“Vintage(复古色调)”,另一个是“Ink Effects(水墨效果)”。选择“Vintage”可以看到一组六个不同效果,每组都能给你的照片带来一种温馨和古色古香的感觉。选中了所喜欢的效果后,可以使用指头在照片上进行捏放滑动等动作,以调节该效果的大小尺寸和所在位置。如果不喜欢复古效果,你可以直接在右侧的“Vignette(装饰)”图标上点击,以关闭该效果。(如果你找不到的话,可以点击顶部的黄色问号标记)
图二Vintage效果可以让你的照片变得温暖温馨。捏放和滑动照片可以进行装饰的调整。
“Ink Effects(水墨效果)”则可以给你的照片带来特别的纹理以及锯齿状的毛边,让它们看起来好象是画在一幅破旧的帆布之上。和Vintage一样,共有六种不同效果供你选择。找到自己喜欢的效果后,在照片的左侧和右侧刷动,即可增加或者减少毛边;而在上下刷动,则是调节帆布材质的表现。需要注意的是,这些效果是被施加于其他编辑之上的,所以你无法将不同效果组合起来。
图三有六种墨水特效可供选择
扩展动态范围
在某些特定的照明条件之下,你会发现所获得照片的动态范围相当有限——简单点说,就是你会发现,照片上最暗的地方并不是纯黑色,而最亮的地方也不是纯白色。其结果就是,你的照片要么看起来很单调,要么看起来很过度。
好在iPhoto提供了一种快速解决照片曝光问题的方法。打开iPhoto,选中照片后点击“Edit(编辑)”。然后点击底部左侧的“Exposure(曝光)”图标。现在你照片的下面会显示一个滑动条,你可以拖动它对照片的曝光度及对比度进行调节。不过,要留意的是,其实这个滑块还有更多的含义!滑块所处的位置,其实就给了你关于照片动态范围的重要信息,其性质类似于台式机软件上的直方图。在左侧,你可以看到一个银色矩形,显示了照片中最黑点的数值,而另一侧则是另一个银色矩形,显示了照片中最亮点的数值。
对着两端的细杠分别拖动这些控制滑块,你就可以扩大照片的整体动态范围,因为两个细杠分别代表了可用的最黑位置和最亮位置。(注意,如果你超过细杠越界太多,两端会变成红色,提醒你正失去阴影的细节,或是高光部分产生白斑)。正确设定了动态范围之后,就可以使用滑动条的“亮度和对比度”控制来对曝光进行调节了。记住,任何时候,你都可以点击右上角的“Original(初始状态)”图标,来进行效果的对比衡量。
图四如果曝光滑块并未触及到两侧的细杠,则意味着你的照片并不具备完全的动态范围。
使用“笔画显示(Show Strokes)”以及“边缘检测(Edge Detection)”进行精确编辑
虽然iPhoto提供了一批调整用的笔刷,比如“Saturation(饱和)”,再比如“Sharpen(锐化)”,但仅仅使用手指点触有时候的确很难进行精确的操作。时不时的,你的手指就会触及你不希望修改的区域。这个问题有个很好的解决办法,那就是将“Edge Detection(边缘检测)”和“Show Strokes(显示笔画)”两者结合起来使用。
打开iPhoto,选中一幅打算调整的照片。点击“Edit(编辑)”,然后点击“Brushes(笔刷)”。选中一个笔刷——在本例中,我选择的是“saturate(饱和)”——然后再点击底部右侧的“Edge Detection(边缘检测)”图标。现在,点击紧挨着它的齿轮图标,进入笔刷控制。第二个选项就是“Show Strokes(显示笔画)”;打开它,然后在你的图片上任意位置点击一下,关掉笔刷控制的弹窗。
图五使用“显示笔画(Show Strokes)”以及“Edge Detection(边缘检测)”进行更精准的编辑控制
将手指放在一个已经预先定义好边缘的区域中心——如果需要的话,先放大一下照片——再把手指放进去。然后你会看到,你按的地方会变成红色高亮。继续滑动你的手指,将整个打算编辑的区域都变成高亮。感谢iPhoto的边缘检测,你可以看到,虽然你的手指头越过了物体边界,但红色高亮并不会越界(如果你不巧搞了几个杂乱的笔画出来,记得可以使用“Erase(擦除)”将其去掉)
在高亮了所有打算编辑的地方之后,点击“齿轮”图标返回笔刷控制,关掉“Show Strokes(显示笔画)”。你刚才这番努力的结果会立刻显现出来;如果你觉得效果有些“过了”的话,只需在该窗口的顶部,使用滑块降低该效果的强度即可。