iOS面试知识点收集iOS Developer程序员

IOS面试题(一)

2017-04-01  本文已影响161人  upupSue

Object-c的类可以多重继承么?可以实现多个接口么?

Object-c的类不可以多重继承;可以实现多个接口,通过实现多个接口可以完成C++的多重继承;

重写一个类的方式用继承好还是分类好?

具体情况具体分析。如果希望影响所有使用这个类或者子类的地方,考虑使用类别。如果只是想在某些位置使用新功能,考虑使用继承。继承时重写的方法只会影响新创建的类型。不过考虑到上面的第三点,慎用类别的方法重写功能。

简述类目优点和缺点?

优点:

(1)可以将类的实现分散到多个不同文件或多个不同框架中,方便代码管理。也可以对框架提供类的扩展(因为框架类没有源码,不能修改)。

(2)创建对私有方法的前向引用:如果其他类中的方法未实现,在你访问其他类的私有方法时编译器报错这时使用类别,在类别中声明这些方法(不必提供方法实现),编译器就不会再产生警告

(3)向对象添加非正式协议:创建一个NSObject的类别称为“创建一个非正式协议”,因为可以作为任何类的委托对象使用。

缺点:

(1)无法向类目添加实例变量,如果需要添加实例变量,只能通过定义子类的方式;

(2)类目中的方法与父类方法相比具有更高级别的优先级,如果覆盖父类的方法,可能导致super消息的断裂。因此,最好不要覆盖原始类中的方法。

类别和继承的区别?

category可以在不获悉,不改变原来代码的情况下往里面添加新的方法,只能添加,不能删除修改,并且如果类别和原来类中的方法产生名称冲突,则类别将覆盖原来的方法,因为类别具有更高的优先级。

继承可以增加,修改或者删除方法,并且可以增加属性

什么是block

block是对象,它封装了一段代码,这段代码可以在任何时候执行。Block是一种具有匿名功能的内嵌函数块。Block一般是用来表示、简化一小段的程式码,它特别适合用来建立一些同步执行的程式片段、封装一些小型的工作或是用来做为某一个工作完成时的回传呼叫。格式如下:^(传入参数列) {行为主体};

使用block时什么情况会发生引用循环,如何解决?

一个对象中强引用了block,在block中又使用了该对象,就会发生循环引用。解决方法是将该对象使用weak或者block修饰符修饰之后再在block中使用。

id weak weakSelf = self;或者weak

__typeof(&*self)weakSelf = self该方法可以设置宏

id __block weakSelf = self

KVC and KVO

KVC键值编码,是一种间接操作对象属性的一种机制,可以给属性设置值。通过setValue:forKey:和valueForKey,实现对属性的存取和访问。

KVO键值观察,是一种使用观察者模式来观察属性的变化以便通知注册的观察者。通过注册observing对象addObserver:forKeyPath:options:context:和观察者类必须重写方法observeValueForKeyPath:ofObject:change:context:。

什么是键-值,键路径是什么

模型的性质是通过一个简单的键(通常是个字符串)来指定的。是一种间接访问对象属性的机制。

键路径是一个由用点作分隔符的键组成的字符串,用于指定一个连接在一起的对象性质序列。通过键路径,您可以指定一个任意深度的路径,使其指向相关对象的特定属性。

协议的基本概念和协议中方法默认为什么类型

答:OC中的协议是一个方法列表。它的特点是可以被任何类使用(实现),但它并不是类,自身不会实现这样方法,而由又其他人来实现。协议经常用来实现委托对象(委托设计模式)。如果一个类采用了一个协议,那么它必须实现协议中必须需要实现的方法,在协议中的方法默认是必须实现(@required),添加关键字@optional,表明一旦采用该协议,这些“可选”的方法是可以选择不实现的。

代理的作用?

代理的目的是改变或传递控制链。允许一个类在某些特定时刻通知到其他类,而不需要获取到那些类的指针。可以减少框架复杂度。

简述NotificationCenter、KVC、KVO、Delegate之间的区别?

1.delegate比nsnotification效率高。

2.和delegate一样,KVO和NSNotification的作用也是类与类之间的通信,与delegate不同的是1)这两个都是负责发出通知,剩下的事情就不管了,所以没有返回值,delegate方法往往需要关注返回值;2)delegate只是一对一,而这两个可以一对多。

在objective c中如何实现KVO

答:(1)注册观察者(这里我们需要注意,观察者和被观察者不会被保留也不会被释放)

-(void)addObserver:(NSObject *)observerforKeyPath:(NSString *)keyPath

options:(NSKeyValueObservingOptions)options

context:(void*)context;

(2)接收变更通知-(void)observeValueForKeyPath:(NSString *)keyPath

ofObject:(id)objectchange:(NSDictionary *)changecontext:(void *)context;

(3)移除对象的观察者身份-(void)removeObserver:(NSObject *)observer

forKeyPath:(NSString*)keyPath;

NSNotification的使用

1被观察者自己在必要的方法A里,通过方法postNotificationName:object:来发出通知notificationName这样发送通知者这边的工作就完成了,每次A被调用,就会发送一次通知notificationName。

2谁要监听A的变化,就通过[NSNotificationCenter defaultCenter]的方法addObserver:selector:name:object:为观察者注册监听name为notificationName的通知然后每次发出name为notificationName的通知时,注册监听后的观察者就会调用其自己定义的方法notificationSelector来进行响应。

NSNotification的特点呢,就是需要被观察者先主动发出通知,然后观察者注册监听后再来进行响应,比KVO多了发送通知的一步,但是其优点是监听不局限于属性的变化,还可以对多种多样的状态变化进行监听,监听范围广,使用也更灵活。

对于单例的理解

单例在整个工程中,就相当于一个全局变量,不论在哪里需要用到这个类的实例变量,都可以通过单例方法来取得,而且一旦创建了一个单例类,不论你在多少个界面中初始化调用了这个单例方法取得对象,它们所有的对象都是指向的同一块内存存储空间(即单例类保证了该类的实力对象是唯一存在的一个).

objective-c中要实现一个单例类,至少需要做以下四个步骤:

1).为单例对象实现一个静态实例,并初始化,然后设置成nil,

2).实现一个实例构造方法检查上面声明的静态实例是否为nil,如果是则新建并返回一个本类的实例,

3).重写allocWithZone方法,用来保证其他人直接使用alloc和init试图获得一个新实力的时候不产生一个新实例,

4).适当实现allocWitheZone,copyWithZone,release和autorelease。

什么是深拷贝,浅拷贝

1)深拷贝又叫对象拷贝,系统为对象放在一个新的内存空间中,是真正意义上的复制

2)浅拷贝又叫指针拷贝,不过是给原有对象增加了一次引用计数,这时候相当于retain

3)对于系统的非容器类对象,我们可以认为,如果是对一不可变的对象复制,copy是浅拷贝,mutableCopy是深拷贝,如果是对一可变对象复制,copy和mutableCopy都是深拷贝,但是copy返回的对象是不可变的

4)对于系统的容器类NSArray,NSDictionary来说,对整个容器做copy活mutableCopy操作,不会影响容器中的元素,容器中元素都是浅拷贝,及指针拷贝

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

Objective-C如何对内存管理的,说说你的看法和解决方法?

Objective-C的内存管理主要有三种方式ARC(自动引用计数)、MRC(手动内存计数)、autorelease(自动释放池)。

1)每个对象都有一个引用计数器,每个新对象的计数器是1,当对象的计数器减为0时,就会被销毁

2)通过retain可以让对象的计数器+1、release可以让对象的计数器-1

3)如果你保留了某个对象,你需要(最终)释放或自动释放该对象.必须保持retain方法和release方法的使用次数相等.

4)@property如果用了copy或者retian,就需要对不再使用的属性做一次release操作

5)还可以通过autoreleasepool管理内存

6)如果用ARC,编译器会自动生成管理内存的代码

在objective c中是否支持垃圾回收机制?

答:OC是支持垃圾回收机制的(,但是apple的移动终端中,是不支持GC的,Mac桌面系统开发中是支持的。

什么是ARC技术?与GC是否相同?

答:ARC称之为自动引用计数, ,它与GC的机制是不同的。我们在编写代码时,不需要向对象发送release或者autorelease方法,也不可以调用delloc方法,编译器会在合适的位置自动给用户生成release消息(autorelease),ARC的特点是自动引用技术简化了内存管理的难度。

什么是retain count

答:每一个对象都默认有一个retainCount的属性,数值的多少表示现在有几个实例正在引用它。当它为0时,系统会自动调用dealloc方法,将内存回收。

当我们将一个对象加入自动释放池时,该对象何时被销毁

答:一个事件循环结束后。注意自动释放池没有被释放,而是被排空了,向池发送了drain消息。

当我们调用一个静态方法时,需要对对象进行release吗?

答:不需要,静态方法创建一个对象时,对象已被放入自动释放池。在池被释放时,很有可能被销毁。

循环引用是什么,如何解决这样的问题

答:对象a创建并引用到了对象b;对象b创建并引用到了对象c;对象c创建并引用到了对象b。这时候b和c的引用计数分别是2和1。当a不再使用b,调用release释放对b的所有权,因为c还引用了b,所以b的引用计数为1,b不会被释放。b不释放,c的引用计数就是1,c也不会被释放。从此,b和c永远留在内存中。

这种情况,必须打断循环引用,通过其他规则来维护引用关系。我们常见的delegate往往是assign方式的属性而不是retain方式的属性,赋值不会增加引用计数,就是为了防止delegation两端产生不必要的循环引用。

我们说的OC是动态运行时语言是什么意思?

答:多态。主要是将数据类型的确定由编译时,推迟到了运行时。运行时机制使我们直到运行时才去决定一个对象的类别,以及调用该类别对象指定方法。多态:不同对象以自己的方式响应相同的消息的能力叫做多态。可以说,运行时机制是多态的基础。

ObjC中,与retain配对使用的方法是dealloc还是release,为什么?需要与alloc配对使用的方法是dealloc还是release,为什么?

答:与retain配对使用的方法是release,因为retain使retainCount计数加1,release使retainCount计数减1;。与alloc语义相反的是dealloc,因为:alloc是创建一个对象,,dealloc是销毁一个对象。

属性readwrite,readonly,assign,retain,copy,nonatomic各是什么作用,在那种情况用?

readwrite:是可读可写特性;同时生成get方法和set方法的声明和实现

readonly:是只读特性;只生成get方法的声明和实现

assign:普通赋值,一般常用于基本数据类型,常见委托设计模式,以此来防止循环引用。

retain:保留计数,获得到了对象的所有权。引用计数在原有基础上加1。

copy:一般认为,是在内存中重新开辟了一个新的内存空间,用来存储新的对象,和原来的对象是两个不同的地址,引用计数分别1。但是当copy对象为不可变对象时,那么copy的作用相当于retain。因为,这样可以节约内存空间。

nonatomic:非原子性,set方法的实现不加锁(比atomic性能高)决定编译器生成的setter 、getter是否是原子操作,一般使用nonatomic

atomic提供多线程安全。是防止在写未完成的时候被另外一个线程读取,造成数据错误

常见的object-c的数据类型有那些,和C的基本数据类型有什么区别

1)常用OC类型:NSString、NSArray、NSDictionary、NSData、NSNumber等创建后便是对象,而C语言的基本数据类型int,只是一定字节的内存空间,用于存放数值;

2)NSInteger是基本数据类型,并不是NSNumber的子类,当然也不是NSObject的子类。NSInteger是基本数据类型Int或者Long的别名,它的区别在于,NSInteger会根据系统是32位还是64位来决定是本身是int还是Long

id声明的变量有什么特性?

id声明的变量能指向任何OC对象

具有运行时的特点,在程序运行时才确定对象的类型

不可使用点语法

解释以下关键字:static、self、super用实例说明

答:static:静态全局变量,持久性作用、存储区域在静态区域,它的生命周期和应用进行绑定。程序结束时,由系统自动回收。self:当前消息的接收者。super:向父类发送消息。

解释self = [super init]方法

答:容错处理,当父类初始化失败,会返回一个nil,表示初始化失败。由于继承的关系,子类是需要拥有父类的实例和行为的,因此,我们必须先初始化父类,然后再初始化子类。

当我们释放对象时,为什么需要调用[super dealloc]方法?

答:因为子类是继承自父类,子类中有一些实例变量是继承子父类的,因此,我们需要调用父类方法,将父类所拥有的实例进行释放。

在某个方法中self.name = _name、name = _name他们有区别吗,为什么?

答:是有区别的,前者会对_name对象进行保留或者拷贝操作,而后者是普通赋值。

OC中可修改和不可以修改类型。

1)可修改不可修改的集合类。这个我个人简单理解就是可动态添加修改和不可动态添加修改一样。

2)比如NSArray和NSMutableArray。前者在初始化后的内存控件就是固定不可变的,后者可以添加等,可以动态申请新的内存空间。

什么时候使用NSMutableArray,什么时候使用NSArray?

当数组在程序运行时,需要不断变化的,使用NSMutableArray,当数组在初始化后,便不再改变的,使用NSArray。需要指出的是,使用NSArray只表明的是该数组在运行时不发生改变,即不能往NSAarry的数组里新增和删除元素,但不表明其数组內的元素的内容不能发生改变。NSArray是线程安全的,NSMutableArray不是线程安全的,多线程使用到NSMutableArray需要注意

用@property声明的NSString(或NSArray,NSDictionary)经常使用copy关键字,为什么?如果改用strong关键字,可能造成什么问题?

1)使用copy的目的是为了让本对象的属性不受外界影响,如果使用是strong ,那么这个属性就有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性

2)当属性类型为NSString时,经常用此特质来保护其封装性,因为传递给设置方法的新值有可能指向一个NSMutableString类的实例。此时若是不拷贝字符串,那么设置完属性之后,字符串的值就可能会在对象不知情的情况下遭人更改。所以,这时就要拷贝一份“不可变”的字符串,确保对象中的字符串值不会无意间变动。只要实现属性所用的对象是“可变的”,就应该在设置新属性值时拷贝一份。

nil,NSNULL,NULL区别

nil是指向obj-c中对象的空指针,是一个对象,在o-c中nil对象调用方法不会引起crash。

Nil是指向obj-c中的类的空指针,表示的是一个空类。

NULL是指向任何类型的空指针(如c/c++中的空指针),在objective-c中是一个数值。

NSNULL用于集合操作,在集合对象中,表示一个空值的集合对象。

野指针是什么,iOS 开发中什么情况下会有野指针?

野指针是不为 nil,但是指向已经被释放的内存的指针。空指针是没有存储任何内存地址的指针。

1.指针变量未初始化;2.指针释放后之后未置空;3.指针操作超越变量作用域;

#import跟#include、@class有什么区别?#import<>跟#import”"又什么区别?

1)#import和#include都能完整地包含某个文件的内容,#import能防止同一个文件被包含多次,防止交叉编译

2)@class仅仅是声明一个类名,并不会包含类的完整声明;@class还能解决循环依赖的问题

3)#import<>用来包含系统自带的文件,#import “”用来包含自定义的文件

面向对象的三大特征

封装、继承、多态

1)封装:把具体的对象封装成抽象的类,隐藏内部实现,对象的属性和实现细节,仅对外公开接口,提高代码的安全性,实现模块化调用。好处:使用者只关注接口而不必关注实现,代码的维护性好

2)继承:一个类是另外一个类的子类,子类继承父类就会拥有父类所有的属性和方法,如果对于方法不满意可以重写父类的方法.缺点:1.使程序变得复杂2.破坏了封装性3.降低了可维护性和可扩展性

3)多态:不同对象以自己的方式响应相同的消息的能力叫做多态。引用的多种形态,父类指针指向子类对象,子类可以重写父类的方法,但是父类不能用子类的方法,子类的方法可能各有不同。

@public、@protected、@private它们的含义与作用

(1) @public:对象的实例变量的作用域在任意地方都可以被访问

(2) @protected::对象的实例变量作用域在本类和子类都可以被访问

(3) @private:实例变量的作用域只能在本类中访问

objc优点:

1既具有静态语言的特性(如C++),又有动态语言的效率(动态绑定、动态加载等)

2不是一个过度复杂的C衍生语言

3 Objective-C与C++可混合编程

缺点:

1)不支持命名空间

2)不支持运算符重载

3)不支持多重继承

objc中的类方法和实例方法有什么本质区别和联系?

如果需要访问某个实例的成员变量时,需要改变实例的状态,那么该方法该被定义为实例方法

相反则定义为类方法即静态方法

为什么类方法中不能操作实例成员变量?

类方法就是static修饰的方法,static修饰得方法在加载class得时候就加载完成,这个时候构造方法还没执行,此时非static得属性比如成员变量还没初始化,所以不能调用,因为都还不存在

什么是延迟加载?

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

iOS的系统架构

iOS的系统架构分为(核心操作系统层、(核心服务层、(媒体层和(Cocoa界面服务层、四个层次

frame和bounds有什么不同?

frame指的是:该view在父view坐标系统中的位置和大小。(参照点是父亲的坐标系统)

bounds指的是:该view在本身坐标系统中的位置和大小。(参照点是本身坐标系统)

loadView干嘛用的?

loadView在View为nil时调用,早于ViewDidLoad,通常用于代码实现控件,收到内存警告时会再次调用。loadView默认做的事情是:如果此VIewcontroller存在一个对应的nib文件,那么就加载这个nib。否则,就创建一个UIView对象。如果你用Interface Builder来创建界面,那么不应该重载这个方法。

如果你想自己创建View对象,那么可以重载这个方法,此时你需要自己给View属性赋值。你自定义的方法不应该调用super。如果你需要对View做一些其他定制操作,在ViewDidload中去做。

loadView,viewDidLoad,viewDidUnload,didReceiveMemoryWarning分别是什么时候调用的,在自定义viewController的时候这几个函数里面应该做什么工作

(1)loadView在加载self.view时会调用,viewDidLoad当界面显示的时候会调用,viewDidUnload在self.view = nil的时候会调用

(2)在viewDidLoad中写用纯代码方式创建的各个view,以及self.view创建出来后要执行的操作

(3)viewDidUnload里执行view的release操作,如果是代码创建的要在这里release,IBOutlet创建的不需要release,会自动release。

(4)当应用程序接收到系统的内容警告时,就有可能调用控制器的didRece…Warning方法

如何高性能的给UIImageView加个圆角?

一般情况下给UIKit的控件添加圆角都是改变clipsToBounds和layer.cornerRadius.但是,这样使用这样的方法会强制Core Animation提前渲染屏幕的离屏绘制,而离屏绘制就会为性能带来负面影响.

使用贝塞尔曲线"切割"这个图片,给UIImageView添加了的圆角.

使用drawRect有什么影响?

1)drawRect主要的缺点就是它处理touch事件的方式:每次按钮被点击后,都会用setNeddsDisplay进行强制重绘,每次单点事件触发两次执行。这样的话从性能的角度来说,对CPU和内存来说都是欠佳的。

drawRect和layoutSubviews的区别

1)当调用setNeedsDisplay时会自动调用drawRect方法,这样就可以拿到currentContext就可以画画了,而setNeedsLayout会自动调用layoutSubViews,就可以处理子视图的一些数据。

layoutSubViews方便数据计算,drawRect方便视图重绘

2)layoutSubviews在以下情况下会被调用:

addSubview,

frame发生改变,

滚动一个scrollView,

旋转screen,

改变子view的frame,

直接调用setLayoutSubviews,

直接调用setNeedsLayout

3)drawRect会在以下情况被调用:

在viewDidLoad走完后会调用,

调用sizeToFit后会被调用,

设置contentMode为UIViewContentModeRedraw,那么每次frame修改会自动调用drawRect:

直接调用setNeedsDisplay

宽度固定的情况下,如何计算UILabel要显式的内容所需要的高度

文本内容调用boundingRectWithSize方法,传入参数size,width固定,高度填写MAXFLOAT,传入font属性,返回一个size,size中的高度即为适应后的高度。

描述一下UITableView的重用机制

(1)tableView重用机制是苹果为了实现大量数据显示而采用的一种节省内存的机制

(2)为什么要重用呢?假设一个tableVIew有几百个cell,如果所有cell都要占用内存的话消耗是很大的,很容易出现memoryWarning,甚至crash

(3)重用机制的原理:cell创建的时候会标示一个identifier,tableVIew显示后只会创建一个屏幕大小的cell个数放到visiableCells中,当你上滑屏幕的时候,上边的cell会依次进入可重用队列reusableTableCells,下方要显示的cell从可重用队列reusableTableCells中根据identifier取出重用的cell,修改它显示的数据,来实现可显示大量数据的目的。

tableview的优化

优化:

1)正确的复用cell。

2)减少在返回每个cell里面的处理逻辑和处理时间。尽量将数据进行缓存和复用。

3)尽量减少处理加载和计算的时间,不阻塞UI线程。

4)尽量使用绘制每个cell。

5)设置每个cell的opaque属性。

6)尽量返回每行固定的height。

7)在每个cell减少图形效果。

8)分段加载数据。

tabbar和toolbar分别是什么?两者之间有何共同点和不同点。

tabbar是显示不同页面用的控件,toolbar一般用于不跳转页面,是在一个页面显示不同内容或者是做不同操作

IBOutlet连出来的视图属性为什么可以被设置成weak?

因为既然有外链那么视图在xib或者storyboard中肯定存在,视图已经对它有一个强引用了。

什么叫回调,什么叫回调函数用block怎么实现回掉调

比如你调用一个方法下载图片,下载完后要返回调用的地方刷新UI,这个返回的过程就叫回调,在a类中写一个方法,到b类中调用

代理,block,通知都可以实现回调。

xib,storyboard,手动书写代码

1)xib(interface buider),方便对界面进行编辑。可以在窗口上面直接添加各种视图,优点:直接看到界面的效果,操作简单。缺点:不方便对视图进行动态控制,不灵活。

2)手动编写代码,继承(主要是UIView,UIViewController),优点:可以对视图进行定制,灵活控制方便。缺点:不能马上看到效果,复杂。

3)storyboard(故事板在ios6加入)。优点:可以看到界面效果,能同时进行多个界面的交互,高效快速。缺点:不能进行进行界面的定制,却笑灵活性。

4)xib和storyboard主要用于界面中的元素位置固定和清楚里面有哪些元素。但是如果需要动态变化界面还是手动编写代码比较好。一般还是各种方式混合使用。

CAlayer介绍

一个UIView包含CALayer树,CALayer是一个数据模型。包含了一些用来显示的对象,在UIView的子类中都可以找到层这个组件,层是位于固定的画布上的一个子片,可以被覆盖。层是彼此堆叠在一起的最终产生一个界面。除此之层可以包含多个层,通过层可以操作位于此层上面的其他内容,例如旋转,动画,翻页等。

UIView与CLayer有什么区别?

1).UIView是iOS系统中界面元素的基础,所有的界面元素都是继承自它。它本身完全是由CoreAnimation来实现的。它真正的绘图部分,是由一个CALayer类来管理。UIView本身更像是一个CALayer的管理器,访问它的跟绘图和跟坐标有关的属性。

2).UIView有个重要属性layer,可以返回它的主CALayer实例。

3). CALayer的坐标系统比UIView多了一个anchorPoint属性,使用CGPoint结构表示,值域是0~1,是个比例值。这个点是各种图形变换的坐标原点,同时会更改layer的position的位置,它的缺省值是{0.5,0.5},即在layer的中央

UIScrollView的contentSize、contentOffSet和contentInset属性的区别

contentSize表示UIScrollView滚动区域的大小。UIScrollView的frame属性在设置好了以后不会随内容的变化而变化。

contentOffSet表示是UIScrollView当前显示区域顶点相对于frame顶点的偏移量,一般用来设置UIScrollView显示的位置。

contentInset表示是scrollview的contentView的顶点相对于scrollview的位置,

Objective-C堆和栈的区别?

1)管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生memory leak。

2)碎片问题:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出

3)分配方式:堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。

4)分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的。

5)队列和栈是两种不同的数据容器。从”数据结构”的角度看,它们都是线性结构,即数据元素之间的关系相同。队列是一种先进先出的数据结构,它在两端进行操作。栈是一种先进后出的数据结构,它只能在栈顶进行操作。

c和obj-c如何混用?

1)obj-c的编译器处理后缀为m的文件时,可以识别obj-c和c的代码,处理mm文件可以识别obj-c,c,c++代码,但cpp文件必须只能用c/c++代码,而且cpp文件include的头文件中,也不能出现obj- c的代码,因为cpp只是cpp。

2)在mm文件中混用cpp直接使用即可,所以obj-c混cpp不是问题

3)在cpp中混用obj- c其实就是使用obj-c编写的模块是我们想要的。如果模块以类实现,那么要按照cpp class的标准写类的定义,头文件中不能出现obj-c的东西,包括#import cocoa的。实现文件中,即类的实现代码中可以使用obj-c的东西,可以import,只是后缀是mm。如果模块以函数实现,那么头文件要按c的格式声明函数,实现文件中,c++函数内部可以用obj-c,但后缀还是mm或m。总结:只要cpp文件和cpp include的文件中不包含obj-c的东西就可以用了,cpp混用obj-c的关键是使用接口,而不能直接使用实现代码,实际上cpp混用的是obj-c编译后的o文件,这个东西其实是无差别的,所以可以用。obj-c的编译器支持cpp。

如何将产品进行多语言发布?

程序国际化;比如:本地化应用程序名称(1、选中工程,Info—Localizations点击“+”添加要国际化的语言。(2、在InfoPlist.strings右边会多出一个三角形,点击展开可看到InfoPlish.strings(english)和InfoPlish.strings(chinese)两个版本的文件; (3、在InfoPlish.strings(english)文件中加入:CFBundleDisplayName="Program";其中“Program”为英文应用程序名称,同理在InfoPlish.strings(chinese)文件中加入: CFBundleDisplayName ="应用程序";其中“应用程序”为中文名称,注意:CFBundleDisplayName加不加双引号都行;(4、编辑Info.plist,添加一个新的属性Application has localizeddisplay name,设置其类型为boolean,并将其value设置为YES即可。

Scoket连接和HTTP连接的区别

HTTP连接:短连接,

Socket连接:长连接,

GET和POST的区别:

POST请求:参数在请求数据区放着,相对GET请求更安全,并且数据大小没有限制。把提交的数据放置在HTTP包的包体中.

GET提交的数据会在地址栏显示出来,而POST提交,地址栏不会改变。

如何理解MVC设计模式

MVC是一种架构模式,M表示MOdel,V表示视图View,C表示控制器Controller:

Model负责存储、定义、操作数据;

View用来展示书给用户,和用户进行操作交互;

Controller是Model和View的协调者,Controller把Model中的数据拿过来给View用。Controller可以直接与Model和View进行通信,Model和View不能直接进行通信,这样会违背MVC设计模式。

如何理解MVVM设计模式。

ViewModel层,就是View和Model层的粘合剂,他是一个放置用户输入验证逻辑,视图显示逻辑,发起网络请求和其他各种各样的代码的极好的地方。说白了,就是把原来ViewController层的业务逻辑和页面逻辑等剥离出来放到ViewModel层。

view和view controller正式联系在一起,我们把它们视为一个组件。他们从ViewModel层获取数据,然后显示

线程与进程的区别和联系?

一个程序至少要有进城,一个进程至少要有一个线程。

进程:资源分配的最小独立单元,进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。

线程:进程下的一个分支,是进程的实体,是CPU调度和分派的基本单元,它是比进程更小的能独立运行的基本单位,线程自己基本不拥有系统资源,只拥有一点在运行中必不可少的资源(程序计数器、一组寄存器、栈),但是它可与同属一个进程的其他线程共享进程所拥有的全部资源。

联系:进程和线程都是程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。

区别:进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径,没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。

对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。

多线程编程:是防止主线程堵塞、增加运行效率的最佳方法。

NSThread:当需要进行一些耗时操作时会把耗时的操作放到线程中。线程同步:多个线程同时访问一个数据会出问题,NSlock、线程同步块、@synchronized(self){}。

NSOperationQueue操作队列(不需考虑线程同步问题)。编程的重点都放在main里面,NSInvocationOperation、BSBlockOperation、自定义Operation。创建一个操作绑定相应的方法,当把操作添加到操作队列中时,操作绑定的方法就会自动执行了,当把操作添加到操作队列中时,默认会调用main方法。

GCD宏大的中央调度,串行队列、并发队列、主线程队列;

同步和异步

同步指第一个任务不执行完,不会开始第二个,异步是不管第一个有没有执行完,都开始第二个。

串行和并行:串行是多个任务按一定顺序执行,并行是多个任务同时执行;

上一篇 下一篇

猜你喜欢

热点阅读