黑马程序员面试技巧

2022-08-14

第一篇:黑马程序员面试技巧

黑马程序员: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框架和引入主头文件(iOS7.0+ 不需要) 2>. 初始化一个CAAnimation对象,并设置一些动画相关属性

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无法确保计时器实际被触发的准确时间 使用方法:

定义CADisplayLink并制定触发调用方法 将显示链接添加到主运行循环队列

第二篇:黑马程序员:IOS面试宝典之OC语言

OC语言(★★)

有人可能会问对于我们学iOS的同学来讲,面试还会问Objective-C基础吗?答案是会的,但是不会太多,因此我给了两颗星的重要程度。一般笔试的时候出现Objective-C基础题的概率比较大,口头面试的时候比较少,比如自己在面试的时候一些对基础知识比较看重的面试官会深究着Objective-C基础去问,比如Objective-C内存管理等等。

一、Objective-C语法

1. 面向对象都有哪些特性以及你对这些特性的理解

继承:继承是从已有类得到继承信息创建新类的过程。提供继承信息的类被称为父类(超类、基类);得到继承信息的类被称为子类(派生类)。继承让变化中的软件系统有了一定的延续性,同时继承也是封装程序中可变因素的重要手段。

封装:通常认为封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。面向对象的本质就是将现实世界描绘成一系列完全自治、封闭的对象。我们在类中编写的方法就是对实现细节的一种封装;我们编写一个类就是对数据和数据操作的封装。可以说,封装就是隐藏一切可隐藏的东西,只向外界提供最简单的编程接口。

多态性:多态性是指允许不同子类型的对象对同一消息作出不同的响应。简单的说就是用同样的对象引用调用同样的方法但是做了不同的事情。多态性分为编译时的多态性和运行时的多态性。如果将对象的方法视为对象向外界提供的服务,那么运行时的多态性可以解释为:当A系统访问B系统提供的服务时,B系统有多种提供服务的方式,但一切对A

系统来说都是透明的。方法重载(overload)实现的是编译时的多态性(也称为前绑定),而方法重写(override)实现的是运行时的多态性(也称为后绑定)。运行时的多态是面向对象最精髓的东西,要实现多态需要做两件事:1. 方法重写(子类继承父类并重写父类中已有的或抽象的方法);2. 对象造型(用父类型引用引用子类型对象,这样同样的引用调用同样的方法就会根据子类对象的不同而表现出不同的行为)。

抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么。

2. 我们说的Objective-C是动态运行时语言是什么意思? (When we call objective c is runtime language what does it mean?) 主要是将数据类型的确定由编译时,推迟到了运行时。这个问题其实浅涉及到两个概念,运行时和多态。简单来说, 运行时机制使我们直到运行时才去决定一个对象的类别,以及调用该类别对象指定方法。多态:不同对象以自己的方式响应相同的消息的能力叫做多态。意思就是假设生物类(life)都用有一个相同的方法-eat;那人类属于生物,猪也属于生物,都继承了life后,实现各自的eat,但是调用是我们只需调用各自的eat方法。也就是不同的对象以自己的方式响应了相同的消息(响应了eat这个选择器)。因此也可以说,运行时机制是多态的基础. 3. readwrite,readonly, assign,retain,copy,nonatomic, strong, weak属性的作用?并区别strong(强引用)、weak(弱引用)?什么情况使用copy,assign和retain? readwrite 是可读可写特性;需要生成getter方法和setter方法时;

readonly 是只读特性只会生成getter方法不会生成setter方法,不希望属性在类外改变;

assign 是赋值特性,setter方法将传入参数赋值给实例变量;仅设置变量时;, assign用于简单数据类型,如NSInteger,double,bool; retain 表示持有特性,setter方法将传入参数先保留,再赋值,传入参数的retaincount会+1;

copy 表示赋值特性,setter方法将传入对象复制一份;需要完全一份新的变量时; nonatomic 非原子操作,决定编译器生成的setter getter是否是原子操作; atomic表示多线程安全,一般使用nonatomic。

retain 和copy用户对象,copy用于当 a指向一个对象, b也想指向同样的对象的时候,如果用assign,a如果释放,再调用b会crash,如果用copy 的方式,a和b各自有自己的内存,就可以解决这个问题。retain 会使计数器加1,也可以解决assign的问题。另外:atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作。在多线程环境下,原子操作是必要的,否则有可能引起错误的结果。

其实从这个也可以引申到内存管理的一系列问题.面试官会让你讲讲MRC和ARC的理解,随即也引申出Block的内存机制,为啥推荐Block用copy,Block会存在哪些内存问题?循环引用?

4.分别描述内存管理要点、autorelease、release、NSAutoreleasePool?并说明autorelease是什么时候被release的?简述什么时候由你负责释放对象,什么时候不由你释放?[NSAutoreleasePool release]和[NSAutoreleasePool drain]有什么区别? 内存管理要点: Objective-C 使用引用计数机制(retainCount)来管理内存。内存每被引用一次,该内存的引用计数+1,每被释放一次引用计数-1。当引用计数 = 0 的时候,调用该对象的 dealloc 方法,来彻底从内存中删除该对象。 alloc,allocWithZone,new(带初始化)时:该对象引用计数 +1;

retain:手动为该对象引用计数 +1; copy:对象引用计数 +1;

mutableCopy:生成一个新对象,新对象引用计数为 1; release:手动为该对象引用计数 -1;

autorelease:把该对象放入自动释放池,当自动释放池释放时,其内的对象引用计数 -1。

NSAutoreleasePool: NSAutoreleasePool是通过接收对象向它发送的autorelease消息,记录该对象的release消息,当自动释放池被销毁时,会自动向池中的对象发送release消息。autorelease 是在自动释放池被销毁,向池中的对象发送release只能释放自己拥有的对象, 区别是:在引用计数环境下(在不使用ARC情况下),两者基本一样,在GC(垃圾回收制)环境下,release 是一个no-op(无效操作),所以无论是不是GC都使用drain

面试中内存管理,release和autorelease的含义?这里尤其要强调下autorelease,它引申出自动释放池,也能引申出Run loop! 5. 自动释放池是什么,如何工作 ? 当 您向一个对象发送一个autorelease消息时,Cocoa就会将该对象的一个引用放入到最新的自动释放池。它仍然是个对象,因此自动释放池定义的作用域内的其它对象可以向它发送消息。当程序执行到作用域结束的位置时,自动释放池就会被释放,池中的所有对象也就被释放。

1>. Objective-C 是 通过一种"referring counting"(引用计数)的方式来管理内存的, 对象在开始分配内存(alloc)的时候引用计数为1,以后每当碰到有copy,retain的时候引用计数都会加1, 每当碰到release和autorelease的时候引用计数就会减1,如果此对象的计数变为了0, 就会被系统销毁. 2>. NSAutoreleasePool 就是用来做引用计数的管理工作的,这个东西一般不用自己管理. 3>. autorelease和release没什么区别,只是引用计数减1的时机不同而已,autorelease会在对象的使用真正结束的时候才做引用计数减1. 6. IPhone OS有没有垃圾回收?autorelease 和垃圾回收制(gc)有什么关系? IPhone OS 中没有垃圾回收。autorelease只是延迟释放,gc是每隔一段时间询问程序,看是否有无指针指向的对象,若有,就将它回收。他们两者没有什么关系。

7. 简述NotificationCenter、KVC、KVO、Delegate?并说明它们之间的区别? KVO(Key-Value- Observing):是键值监听,键值观察机制,当观察者为一个对象的属性进行了注册,被观察对象的isa指针被修改的时候,isa指针就会指向一个中间类,而不是真实的类。所以 isa指针其实不需要指向实例对象真实的类。所以我们的程序最好不要依赖于isa指针。在调用类的方法的时候,最好要明确对象实例的类名

KVC(Key-Value-Coding)内部的实现:是键值编码,一个对象在调用setValue的时候,(1)首先根据方法名找到运行方法的时候所需要的环 境参数。(2)他会从自己isa指针结合环境参数,找到具体的方法实现的接口。(3)再直接查找得来的具体的方法实现。 Delegate:代理的目的是改变或传递控制链。允许一个类在某些特定时刻通知到其他类,而不需要获取到那些类的指针。可以减少框架复杂度。消息的发送者(sender)告知接收者(receiver)某个事件将要发生,delegate同意然然后发送者响应事件,delegate机制使得接收者可以改变发送者的行为。通常发送者和接收者的关系是直接的一对多的关系。

Notification:消息的发送者告知接收者事件已经发生或者将要发送,仅此而已,接收者并不能反过来影响发送者的行为。通常发送者和接收者的关系是间接的多对多关系。

1). 效率肯定是delegate比nsnotification高。

2). delegate方法比notification更加直接,最典型的特征是,delegate方法往往需要关注返回值,也就是delegate方法的结果。比如-windowShouldClose:,需要关心返回的是yes还是no。所以delegate方法往往包含should这个很传神的词。也就是好比你做我的delegate,我会问你我想关闭窗口你愿意吗?你需要给我一个答案,我根据你的答案来决定如何做下一步。相反的,notification最大的特色就是不关心接受者的态度,我只管

把通告放出来,你接受不接受就是你的事情,同时我也不关心结果。所以notification往往用did这个词汇,比如NSWindowDidResizeNotification,那么nswindow对象放出这个notification后就什么都不管了也不会等待接受者的反应。

1)两个模块之间联系不是很紧密,就用notification传值,例如多线程之间传值用notificaiton。

2)delegate只是一种较为简单的回调,且主要用在一个模块中,例如底层功能完成了,需要把一些值传到上层去,就事先把上层的函数通过delegate传到底层,然后在底层call这个delegate,它们都在一个模块中,完成一个功能,例如说 NavgationController 从 B 界面到A 点返回按钮 (调用popViewController方法) 可以用delegate比较好。

What is lazy loading? 就是懒汉模式,只在用到的时候才去初始化。也可以理解成延时加载。我觉得最好也最简单的一个列子就是tableView中图片的加载显示了。一个延时载,避免内存过高,一个异步加载,避免线程堵塞。

9. OC有多继承吗?没有的话可以用什么方法替代? 多继承即一个子类可以有多个父类,它继承了多个父类的特性。Object-c的类没有多继承,只支持单继承,如果要实现多继承的话,可以通过类别和协议的方式来实现,OC类似于多继承,是在用protocol委托代理来实现的;可以实现多个接口,通过实现多个接口可以完成C++的多重继承;Category是类别,一般情况用分类好,用Category去重写类的方法,仅对本Category有效,不会影响到其他类与原有类的关系。

10. 分别描述类别(categories)和延展(extensions)是什么?以及两者的区别?继承和类别在实现中有何区别?为什么Category只能为对象添加方法,却不能添加成员变量? 类别:在没有原类.m文件的基础上,给该类添加方法;

延展:一种特殊形式的类别,主要在一个类的.m文件里声明和实现延展的作用,就是给某类添加私有方法或是私有变量。两个的区别:延展可以添加属性并且它添加的方法是必须要实现的。延展可以认为是一个私有的类目。

继承和类别在实现中的区别:类别可以在不获悉,不改变原来代码的情况下往里面添加新的方法,只能添加,不能删除修改。并且如果类别和原来类中的方法产生名称冲突,则类别将覆盖原来的方法,因为类别具有更高的优先级。 Category只能为对象添加方法,却不能添加成员变量的原因:如果可以添加成员变量,添加的成员变量没有办法初始化

11. Objective-C有私有方法么?私有变量呢?如多没有的话,有没有什么代替的方法? objective-c类里面的方法只有两种, 静态方法和实例方法.但是可以通过把方法的声明和定义都放在.m文件中来实现一个表面上的私有方法。有私有变量,可以通过@private来修饰,或者把声明放到.m文件中。在Objective‐C中,所有实例变量默认都是私有的,所有实例方法默认都是公有的

12. #include与#import的区别? #import与@class的区别? #import指令是Object-C针对#include的改进版本,#import确保引用的文件只会被引用一次,这样你就不会陷入递归包含的问题中。

#import与@class二者的区别在于:

1>#import会链入该头文件的全部信息,包括实体变量和方法等;而@class只是告诉编译器,其后面声明的名称是类的名称,至于这些类是如何定义的,暂时不用考虑。

2>在头文件中,一般只需要知道被引用的类的名称就可以了。不需要知道其内部的实体变量和方法,所以在头文件中一般使用@class来声明这个名称是类的名称。而在实现类里面,因为会用到这个引用类的内部的实体变量和方法,所以需要使用#import来包含这个被引用类的头文件。

3>在编译效率方面考虑,如果你有100个头文件都#import了同一个头文件,或者这些文件是依次引用的,如A–>B, B–>C, C–>D这样的引用关系。当最开始的那个头文件有变化的话,后面所有引用它的类都需要重新编译,如果你的类有很多的话,这将耗费大量的时间。而是用@class则不会。

4>如果有循环依赖关系,如:A–>B, B–>A这样的相互依赖关系,如果使用#import来相互包含,那么就会出现编译错误,如果使用@class在两个类的头文件中相互声明,则不会有编译错误出现。所以,一般来说,@class是放在interface中的,只是为了在interface中引用这个类,把这个类作为一个类型来用的。在实现这个接口的实现类中,如果需要引用这个类的实体变量或者方法之类的,还是需要import在@class中声明的类进来.

13. 浅复制和深复制的区别? (Difference between shallow copy and deep copy?) 浅层复制(copy):只复制指向对象的指针,而不复制引用对象本身。意思就是说我有个A对象,复制一份后得到A_copy对象后,对于浅复制来说,A和A_copy指向的是同一个内存资源,复制的只不过是是一个指针,对象本身资源还是只有一份,那如果我们对A_copy执行了修改操作,那么发现A引用的对象同样被修改,这其实违背了我们复制拷贝的一个思想。

深层复制(mutableCopy):复制引用对象本身。深复制就好理解了,内存中存在了两份独立对象本身,当修改A时,A_copy不变。

用网上一哥们通俗的话将就是:

浅复制好比你和你的影子,你完蛋,你的影子也完蛋

深复制好比你和你的克隆人,你完蛋,你的克隆人还活着。

14. 类变量的@protected,@private,@public,@package声明各有什么含义? 变量的作用域不同,@protected 该类和所有子类中的方法可以直接访问这样的变量,这是默认的;@private 该类中的方法可以访问这样的变量,子类不可以; @public除了自己和子类方法外,也可以被其他类或者其他模块中的方法访问;@package 目前尚未得出结论.

15. static 关键字的作用? 1>函数体内 static 变量的作用范围为该函数体,不同于 auto 变量,该变量的内存只被分配一次, 因此其值在下次调用时仍维持上次的值;

2>在模块内的 static 全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;

3>在模块内的 static 函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明 它的模块内;

4>在类中的 static 成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;

5>在类中的 static 成员函数属于整个类所拥有,这个函数不接收 this 指针,因而只能访问类的static 成员变量

16. 关键字volatile有什么含意?并给出三个不同的例子

一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:

• 并行设备的硬件寄存器(如:状态寄存器)

• 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables) • 多线程应用中被几个任务共享的变量

17. Objective-C与C、C+++之间的联系和区别?

Objective-C和C++都是C的面向对象的超集。

Object与C++的区别主要点:Objective-C是完全动态的,支持在运行时动态类型决议(dynamic typing),动态绑定(dynamic binding)以及动态装载(dynamic loading);而C++是部分动态的,编译时静态绑定,通过嵌入类(多重继承)和虚函数(虚表)来模拟实现。

Objective-C 在语言层次上支持动态消息转发,其消息发送语法为 [object function];而且C++ 为 object->function()。两者的语义也不同,在 Objective-C 里是说发送消息到一个对象上,至于这个对象能不能响应消息以及是响应还是转发消息都不会 crash;而在 C++ 里是说对象进行了某个操作,如果对象没有这个操作的话,要么编译会报错(静态绑定),要么程序会 crash 掉的(动态绑定)。

18. 目标-动作机制

目标是动作消息的接收者。一个控件,或者更为常见的是它的单元,以插座变量(参见"插座变量"部分)的形式保有其动作消息的目标。

动作是控件发送给目标的消息,或者从目标的角度看,它是目标为了响应动作而实现的方法. 程序需要某些机制来进行事件和指令的翻译。这个机制就是目标-动作机制。

19. 动态绑定

在运行时确定要调用的方法 , 动态绑定将调用方法的确定也推迟到运行时。在编译时,方法的调用并不和代码绑定在一起,只有在消实发送出来之后,才确定被调用的代码。通过

动态类型和动态绑 定技术,代码每次执行都可以得到不同的结果。运行时因子负责确定消息的接收者和被调用的方法。运行时的消息分发机制为动态绑定提供支持。当向一个动态类型确定了的对象发送消息时,运行环境系统会通过接收者的isa指针定位对象的类,并以此为起点确定被调用的方法,方法和消息是动态绑定的。而且,不必在Objective-C 代码中做任何工作,就可以自动获取动态绑定的好处。在每次发送消息时,特别是当消息的接收者是动态类型已经确定的对象时,动态绑定就会例行而透明地发生

20. iPad开发与iPhone开发有什么不同?

开发iPad和iPhone应用使用的是相同的SDK,它们之间的区别主要体现在设备硬件和UI操作上。

(1)设备硬件:由于iPad不具备电话功能,iPad1也没有相机,所以相关的特性如电话、SMS等无法使用。

(2)UI操作:由于iPad屏幕大小为9.7英寸,而iPhone的屏幕是3.5英寸,这就决定了两者操作方式的不同。有些控件,如UIPopoverController, UISliptViewController 只能在iPad中使用,而不能在iPhone中使用;而且当需要presentModalViewController时,Window presentation style 只对iPad有效;除此之外,iPad产品开发中还需针对iPad大屏幕考虑加入多指手势以增加用户体验

21. 换肤技术使用了什么技术? 22. 谈谈你对runtime的了解? 23. 算法和数据结构

第三篇:黑马程序员:IOS面试宝典之UITableView与UICollectionView

黑马程序员:IOS面试宝典之UITableView与UICollectionView 1. UITableView的重用机制?(或者如何在一个view上显示多个tableView,tableView要求不同的数据源以及不同的样式 (要求自定义cell), 如何组织各个tableView的delegate和dataSource?请说说实现思路?) 查看UITableView头文件,会找到NSMutableArray*visiableCells,和NSMutableArray*reusableTableCells两 个结构。visiableCells内保存当前显示的cells,reusableTableCells保存可重用的cells。TableView显示之初,reusableTableCel

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的类

5 下拉和上拉的原理? 上拉和下拉的原理可以参照新浪微博的上拉和下拉刷新, 以tableView的上拉刷新为例:

1> 为了进行无缝阅读, 通过tableView的代理方法, willDisplayCell判断是否是最后一行,

2> 如果是最后一行, 在显示最后一行的同时, 判断当前是否存在上拉刷新 3> 如果当前没有上拉刷新, 就进行加载数据, 启动”橘花”

以tableView的下拉刷新为例: 1> 判断当前的上拉刷新视图是否动画

2> 如果没有动画, 就不是上拉刷新 3> 然后下拉刷新加载数据 4> 加载完毕数据关闭刷新

第四篇:黑马程序员自荐信

在当今社会中,需要使用自荐信的场合越来越多,自荐信可以帮助我们更好地提出请求。你还在为写自荐信而苦恼吗?以下是小编为大家整理的黑马程序员自荐信,仅供参考,希望能够帮助到大家。

尊敬的老师:

您好!

在阅读过几十份,甚至上百份的自荐信之后,或许,您已经有了些许疲倦与困意,但还是感谢您打开了我的这封自荐信。对于您来说,或许只是打开了一封信,而对于我来说,您为我开启了一扇窗,一扇可以看见未来,追逐梦想的的窗户。

我是赵玉杰,现在就读于沈阳建筑大学,理学院,信息与计算科学专业,目前大三。说起来,我也和黑马有点缘分,由于专业的.相近性,我在学校学习了c语言,c++语言,java语言,数据库(sql),数据结构(c语言版),计算机网络,操作系统等相关科目,算是有一点基础,但也仅仅只能是基础。这个社会需要的不是基础,而是真才实干。

力,获得足够的项目经验,掌握得心应手的实际操作……就是让我从众多毕业生里面脱颖而出的最佳选择。为了这一目标,我发现了黑马,一匹让我很惊讶的黑马!!!

“黑马程序员”成立于20xx年,20xx年正式上线运营。在短短的3年里,在it培训行业,“黑马程序员”不负众望的成为了一匹业界高度认可的黑马。在短短的四年时间里,“黑马程序员”为社会塑造了一大批it相关行业的精英。从黑马毕业的学员,得到了公司与社会的认可,实现了自己的社会价值,人生目标。在中关村软件园与csdn的大力支持下,在传智播客的教学实施下,“黑马程序员”已经成为了程序员的一种标榜,而能成为“黑马程序员”的一员,是每一个程序员的愿望,更是一种荣耀。而我更是殷切的希望能够成为黑马的一员,让我脱颖而出,让我底气十足。

关于黑马的“0学费入学”教学理念,也是特别吸引我的一大亮点。据我了解,每一位黑马学员都必须通过长达2个月的面试流程,在技术,自学能力,性格,压力,品德等等全方位测试。可以说,黑马程序员训练营的所有学员都是精挑细选出来的。我很期待能与这样的精英一起努力。毕业之后,“工资低于4k,不收任何费用,”只有真正有实力,有责任,有担当的黑马才能说的出口。而从黑马走出的每一个学员,都有能力,有责任,有义务履行我们当初的还款以及相关协议,关于这一点,我坚信不疑。

第五篇:黑马程序员:PHP零基础同学如何学习

零基础大学生们该如何学习php?

我们都知道,php语言作为一种专业建站的语言,没有华而不实,而是经受住了时间考验,成为一种值得学习的语言。现在国内众多的php学校也说明,php语言在当今有着广泛的市场需求。 那么零基础的大学生们如何学习php呢?

对于零基础的大学生们来说,学习php肯定是非常需要毅力的。任何语言的学习都不可能一蹴而就,而是需要花大量时间,消耗大量精力才能学会的。也并不是报了某个班就一定能够学会。 这绝不是打消想立志从事php从业的同学的积极性。想想学会php,要接触的东西实在是太多,不仅html标记,div+css,js这些前台知识需要懂得,而且php语言,samrty模版,ajax,jquery,mysql,linux等等也都需要学习和了解,就是应用工具如框架,也不是一天两天就能够掌握的。

学php难吗?难! 但是任何一门技术,如果轻易就能够让人学会,那也不会称作为技术,因为那样,工作的可替代性太强了。技术,只有难学才会更有价值。 学php有没有技巧,当然有,这也是我在这篇文章想说明的。

php学习第一要点:心态。 虽然目前php语言市场火爆,而且php语言相对于其他的语言来说也更容易学习,但是千万别把php想的太简单,不要全信培训学校的宣传,仿佛零基础的人也能够随随便便就将php学会。失败的案例肯定不少。 当然我们也不要把php想的太难,既然你想从事这方面的工作,那么就要准备全力以赴,破釜沉舟。4个月学会不会,那就坚持到5个月,5个月还不会,那就坚持到6个月。总有一天,你会全面掌握php知识,拿到自己满意的薪酬。

php学习的第二要点:就是学习方法。 在这里,建议大家还是报一个班。一个人学习php,太难,如果说有一群人一起来学习,就能够营造出一种学习php的氛围,有老师教,学习php碰到的问题也可以得到解决。在这里,就会碰到一个问题,那就是一个班,有零基础的,有从事过这方面工作的,php水平可谓是参差不齐,如果是一个零基础的同学学习php,你如何跟上学校的讲课进度? 这里就是我要讲的学习方法,在我们报班前,可以先去网上下载php学习的相关视频,比如网上非常流行的韩顺平的php系列视频(声明:韩老师没给我啥好处费,我也不是托,隔着大老远,我连他老兄的面都没见过的说-_-),就讲的非常好。韩老师的视频讲的很深入、生动,而且有笔记可供下载学习。如果我们把韩老师的视频都看了一两遍再去报班学习php,效果肯定和没看视频效果不一样。

php学习的第三要点:那就是坚持坚持再坚持。抵御诱惑,ASP/PHP/JSP/.NET的对比也许会让我们新手无所适从,也许学了一半PHP,我们又开始打C#的主意,或者有人说JAVA很强,这个时候的我们绝对不能动摇,哪怕我们真想学,也得学会了PHP,然后再学。见异思迁是最不可取的, 狗熊掰玉米就是这个道理,如果经常中途放弃,只能是一无所获,还浪费了N多的时间和经历。当我们花费了大量精力后却又放弃了php,相信我们的心里面会很难过,对未来又会陷入到迷茫中。如果不想有这种体验,那就坚持学会php吧。

上一篇:护理十三五发展规划下一篇:霍乱时期爱情读后感

本站热搜