iOS问答 - 1

作者: 勇敢的_心_ | 来源:发表于2018-05-22 09:13 被阅读93次

    目录

    1. Object-c的类可以多重继承么?可以实现多个接口么?
    2. "#import 跟#include 又什么区别,@class呢, #import<> 跟 #import""又什么区别"?
    3. 属性readwrite,readonly,assign,retain,copy,nonatomic 各是什么作用,在那种情况下用?
    4.对于语句NSString*obj = [[NSData alloc] init]; obj在编译时和运行时分别时什么类型的对象?
    5.常见的object-c的数据类型有那些, 和C的基本数据类型有什么区别?如:NSInteger和int
    6.id 声明的对象有什么特性?
    7.Objective-C如何对内存管理的?
    8. 原子(atomic)跟非原子(non-atomic)属性有什么区别?
    9. 内存管理的几条原则时什么?按照默认法则.那些关键字生成的对象需要手动释放?在和property结合的时候怎样有效的避免内存泄露?
    10. MVC设计模式是什么? 你还熟悉什么设计模式?
    11. 浅复制和深复制的区别?
    12. 类别的作用?继承和类别在实现中有何区别?
    13. 类别和类扩展的区别。
    14. oc中的协议和java中的接口概念有何不同?
    15.什么是KVO和KVC?键路径?
    16. oc中可修改和不可以修改类型。
    17. 我们说的oc是动态运行时语言是什么意思?
    18. 通知和协议的不同之处?
    19. frame和bounds有什么不同?
    20. 方法和选择器有何不同?
    21. OC的垃圾回收机制?
    22. NSOperation queue?
    23.什么是延迟加载?
    24. 是否在一个视图控制器中嵌入两个tableview控制器?
    26.什么时候使用NSMutableArray,什么时候使用NSArray?
    27.在应用中可以创建多少autorelease对象,是否有限制?
    28. 如果我们不创建内存池,是否有内存池提供给我们?
    29. 什么时候需要在程序中创建内存池?
    30. 类NSObject的那些方法经常被使用?
    31.什么是简便构造方法?
    32. 如何使用Xcode设计通用应用?
    33.UIView的动画效果有那些?
    34. 在iPhone应用中如何保存数据?
    35. 什么是coredata?
    36. 什么是NSManagedObject模型?
    37. 什么是NSManagedobjectContext?
    38.什么是谓词?
    39.谈谈对Block 的理解?并写出一个使用Block执行UIVew动画? 40. 写出上面代码的Block的定义。
    41.iOS 中的多线程
    42.在项目什么时候选择使用GCD,什么时候选择NSOperation?
    43.什么是block
    44.block 实现原理
    45.关于block
    46.谈谈Object-C的内存管理方式及过程?
    47.Object-C有私有方法吗?私有变量呢?
    48.Object-C有多继承吗?没有的话用什么代替?cocoa 中所有的类都是NSObject 的子类
    49.内存管理 Autorelease、retain、copy、assign的set方法和含义?
    50. C和obj-c 如何混用
    
    

    1. Object-c的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好?为什么?

    答: Object-c的类不可以多重继承;可以实现多个接口,通过实现多个接口可以完成C++的多重继承;Category是类别,一般情况用分类好,用Category去重写类的方法,仅对本Category有效,不会影响到其他类与原有类的关系。

    2. #import 跟#include 又什么区别,@class呢, #import<> 跟 #import""又什么区别?

    答:#import是Objective-C导入头文件的关键字,#include是C/C++导入头文件的关键字,使用#import头文件会自动只导入一次,不会重复导入,相当于#include和#pragma once;@class告诉编译器某个类的声明,当执行时,才去查看类的实现文件,可以解决头文件的相互包含;#import<>用来包含系统的头文件,#import””用来包含用户头文件。

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

    答:
    1). readwrite 是可读可写特性;需要生成getter方法和setter方法时
    2). readonly 是只读特性 只会生成getter方法 不会生成setter方法 ;不希望属性在类外改变
    3). assign 是赋值特性,setter方法将传入参数赋值给实例变量;仅设置变量时;常见委托设计模式, 以此来防止循环引用。(我们称之为弱引用).
    4). retain 表示持有特性,setter方法将传入参数先保留,再赋值,传入参数的retaincount会+1;
    5). copy 表示赋值特性,setter方法将传入对象复制一份;需要完全一份新的变量时。
    6).nonatomic 非原子操作,决定编译器生成的setter getter是否是原子操作,atomic表示多线程安全,一般使用nonatomic

    @property是一个属性访问声明,扩号内支持以下几个属性:
    1).getter=getterName,setter=setterName,设置setter与 getter的方法名
    2).readwrite,readonly,设置可供访问级别
    2).assign,setter方法直接赋值,不进行任何retain操作,为了解决原类型与环循引用问题
    3).retain,setter方法对参数进行release旧值再retain新值,所有实现都是这个顺序(CC上有相关资料)
    4).copy,setter方法进行Copy操作,与retain处理流程一样,先旧值release,再 Copy出新的对象,retainCount为1。这是为了减少对上下文的依赖而引入的机制。
    5).nonatomic,非原子性访问,不加同步,多线程并发访问会提高性能。注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。锁被加到所属对象实例级。

    4.对于语句NSString*obj = [[NSData alloc] init]; obj在编译时和运行时分别时什么类型的对象?

    答: 编译时是NSString的类型;运行时是NSData类型的对象

    5.常见的object-c的数据类型有那些, 和C的基本数据类型有什么区别?如:NSInteger和int

    答:object-c的数据类型有NSString,NSNumber,NSArray,NSMutableArray,NSData等等,这些都是class,创建后便是对象,而C语言的基本数据类型int,只是一定字节的内存空间,用于存放数值;NSInteger是基本数据类型,并不是NSNumber的子类,当然也不是NSObject的子类。NSInteger是基本数据类型Int或者Long的别名(NSInteger的定义typedef long NSInteger),它的区别在于,NSInteger会根据系统是32位还是64位来决定是本身是int还是Long。

    6.id 声明的对象有什么特性?

    答:Id 声明的对象具有运行时的特性,即可以指向任意类型的objcetive-c的对象;

    7.Objective-C如何对内存管理的?

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

    简述内存管理基本原则:
    之前:OC内存管理遵循“谁创建,谁释放,谁引用,谁管理”的机制,当创建或引用一个对象的时候,需要向她发送alloc、copy、retain消息,当释放该对象时需要发送release消息,当对象引用计数为0时,系统将释放该对象,这是OC的手动管理机制(MRC)。
    目前:iOS 5.0之后引用自动管理机制——自动引用计数(ARC),管理机制与手动机制一样,只是不再需要调用retain、release、autorelease;它编译时的特性,当你使用ARC时,在适当位置插入release和autorelease;它引用strong和weak关键字,strong修饰的指针变量指向对象时,当指针指向新值或者指针不复存在,相关联的对象就会自动释放,而weak修饰的指针变量指向对象,当对象的拥有者指向新值或者不存在时weak修饰的指针会自动置为nil。
    如果使用alloc、copy(mutableCopy)或者retian一个对象时,你就有义务,向它发送一条release或者autorelease消息。其他方法创建的对象,不需要由你来管理内存。
    向一个对象发送一条autorelease消息,这个对象并不会立即销毁, 而是将这个对象放入了自动释放池,待池子释放时,它会向池中每一个对象发送 一条release消息,以此来释放对象.
    向一个对象发送release消息,并不意味着这个对象被销毁了,而是当这个对象的引用计数为0时,系统才会调用dealloc方法,释放该对象和对象本身它所拥有的实例。
    其他注意事项

    如果一个对象有一个_strong类型的指针指向着,找个对象就不会被释放。如果一个指针指向超出了它的作用域,就会被指向nil。如果一个指针被指向nil,那么它原来指向的对象就被释放了。当一个视图控制器被释放时,它内部的全局指针会被指向nil。用法“:不管全局变量还是局部变量用_strong描述就行。
    局部变量:出了作用域,指针会被置为nil。
    方法内部创建对象,外部使用需要添加_autorelease;
    连线的时候,用_weak描述。
    代理使用unsafe_unretained就相当于assign;
    block中为了避免循环引用问题,使用_weak描述;
    声明属性时,不要以new开头。如果非要以new开头命名属性的名字,需要自己定制get方法名,如
    @property(getter=theString) NSString * newString;
    如果要使用自动释放池,用@autoreleasepool{}
    ARC只能管理Foundation框架的变量,如果程序中把Foundation中的变量强制换成COre Foundation中的变量需要交换管理权;
    在非ARC工程中采用ARC去编译某些类:-fobjc-arc。
    在ARC下的工程采用非ARC去编译某些类:-fno-fobjc-arc。

    8. 原子(atomic)跟非原子(non-atomic)属性有什么区别?

    答:
    1). atomic提供多线程安全。是防止在写未完成的时候被另外一个线程读取,造成数据错误
    2). non-atomic:在自己管理内存的环境中,解析的访问器保留并自动释放返回的值,如果指定了 nonatomic ,那么访问器只是简单地返回这个值。

    9. 内存管理的几条原则时什么?按照默认法则.那些关键字生成的对象需要手动释放?在和property结合的时候怎样有效的避免内存泄露?

    答:谁申请,谁释放
    遵循Cocoa Touch的使用原则;
    内存管理主要要避免“过早释放”和“内存泄漏”,对于“过早释放”需要注意@property设置特性时,一定要用对特性关键字,对于“内存泄漏”,一定要申请了要负责释放,要细心。
    关键字alloc 或new 生成的对象需要手动释放;
    设置正确的property属性,对于retain需要在合适的地方释放,

    10. MVC设计模式是什么? 你还熟悉什么设计模式?

    答:
    设计模式:并不是一种新技术,而是一种编码经验,使用比如java中的接口,iphone中的协议,继承关系等基本手段,用比较成熟的逻辑去处理某一种类型的事情,总结为所谓设计模式。面向对象编程中,java已经归纳了23种设计模式。

    mvc设计模式 :模型,视图,控制器,可以将整个应用程序在思想上分成三大块,对应是的数据的存储或处理,前台的显示,业务逻辑的控制。 Iphone本身的设计思想就是遵循mvc设计模式。其不属于23种设计模式范畴。

    代理模式:代理模式给某一个对象提供一个代理对象,并由代理对象控制对源对象的引用.比如一个工厂生产了产品,并不想直接卖给用户,而是搞了很多代理商,用户可以直接找代理商买东西,代理商从工厂进货.常见的如QQ的自动回复就属于代理拦截,代理模式在iphone中得到广泛应用.
    作用:代理的目的是改变或传递控制链。允许一个类在某些特定时刻通知到其他类,而不需要获取到那些类的指针。可以减少框架复杂度。
    另外一点,代理可以理解为java中的回调监听机制的一种类似。

    单例模式:说白了就是一个类不通过alloc方式创建对象,而是用一个静态方法返回这个类的对象。系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为,比如想获得[UIApplication sharedApplication];任何地方调用都可以得到 UIApplication的对象,这个对象是全局唯一的。

    观察者模式: 当一个物体发生变化时,会通知所有观察这个物体的观察者让其做出反应。实现起来无非就是把所有观察者的对象给这个物体,当这个物体的发生改变,就会调用遍历所有观察者的对象调用观察者的方法从而达到通知观察者的目的。

    11. 浅复制和深复制的区别?

    答:浅层复制:只复制指向对象的指针,而不复制引用对象本身。
    深层复制:复制引用对象本身。

    意思就是说我有个A对象,复制一份后得到A_copy对象后,对于浅复制来说,A和A_copy指向的是同一个内存资源,复制的只不过是是一个指针,对象本身资源
    还是只有一份,那如果我们对A_copy执行了修改操作,那么发现A引用的对象同样被修改,这其实违背了我们复制拷贝的一个思想。深复制就好理解了,内存中存在了
    两份独立对象本身。
    用网上一哥们通俗的话将就是:
    浅复制好比你和你的影子,你完蛋,你的影子也完蛋
    深复制好比你和你的克隆人,你完蛋,你的克隆人还活着。

    12. 类别的作用?继承和类别在实现中有何区别?

    答:category 可以在不获悉,不改变原来代码的情况下往里面添加新的方法,只能添加,不能删除修改,并且如果类别和原来类中的方法产生名称冲突,则类别将覆盖原来的方法,因为类别具有更高的优先级。
    类别主要有3个作用:
    1).将类的实现分散到多个不同文件或多个不同框架中。
    2).创建对私有方法的前向引用。
    3).向对象添加非正式协议。
    继承可以增加,修改或者删除方法,并且可以增加属性。

    13. 类别和类扩展的区别。

    答:category和extensions的不同在于 后者可以添加属性。另外后者添加的方法是必须要实现的。
    extensions可以认为是一个私有的Category。

    14. oc中的协议和java中的接口概念有何不同?

    答:OC中的代理有2层含义,官方定义为 formal和informal protocol。前者和Java接口一样。
    informal protocol中的方法属于设计模式考虑范畴,不是必须实现的,但是如果有实现,就会改变类的属性。
    “非正式协议概念其实就是类别的另一种表达方式“这里有一些你可能希望实现的方法,你可以使用他们更好的完成工作”。
    这个意思是,这些是可选的。比如我门要一个更好的方法,我们就会申明一个这样的类别去实现。然后你在后期可以直接使用这些更好的方法。
    这么看,总觉得类别这玩意儿有点像协议的可选协议。”
    现在来看,其实protocal已经开始对两者都统一和规范起来操作,因为资料中说“非正式协议使用interface修饰“,
    现在我们看到协议中两个修饰词:“必须实现(@requied)”和“可选实现(@optional)”。

    15.什么是KVO和KVC?键路径?

    答:
    键路径:在一个给定的实体中,同一个属性的所有值具有相同的数据类型。
    键-值编码技术用于进行这样的查找—它是一种间接访问对象属性的机制。 - 键路径是一个由用点作分隔符的键组成的字符串,用于指定一个连接在一起的对象性质序列。第一个键的性质是由先前的性质决定的,接下来每个键的值也是相对于其前面的性质。
    键路径使您可以以独立于模型实现的方式指定相关对象的性质。通过键路径,您可以指定对象图中的一个任意深度的路径,使其指向相关对象的特定属性。

    KVC:键 – 值编码是一种间接访问对象的属性使用字符串来标识属性,而不是通过调用存取方法,直接或通过实例变量访问的机制。
    很多情况下可以简化程序代码。apple文档其实给了一个很好的例子。
    KVO:键值观察机制,他提供了观察某一属性变化的方法,极大的简化了代码。
    具体用看到嗯哼用到过的一个地方是对于按钮点击变化状态的的监控。
    对于系统是根据keypath去取的到相应的值发生改变,理论上来说是和kvc机制的道理是一样的。

    对于kvc机制如何通过key寻找到value:
    “当通过KVC调用对象时,比如:[self valueForKey:@”someKey”]时,程序会自动试图通过几种不同的方式解析这个调用。首先查找对象是否带有 someKey 这个方法,如果没找到,会继续查找对象是否带有someKey这个实例变量(iVar),如果还没有找到,程序会继续试图调用 -(id) valueForUndefinedKey:这个方法。如果这个方法还是没有被实现的话,程序会抛出一个NSUndefinedKeyException异常错误。
    (cocoachina.com注:Key-Value Coding查找方法的时候,不仅仅会查找someKey这个方法,还会查找getsomeKey这个方法,前面加一个get,或者_someKey以及_getsomeKey这几种形式。同时,查找实例变量的时候也会不仅仅查找someKey这个变量,也会查找_someKey这个变量是否存在。)

    设计valueForUndefinedKey:方法的主要目的是当你使用-(id)valueForKey方法从对象中请求值时,对象能够在错误发生前,有最后的机会响应这个请求。这样做有很多好处,下面的两个例子说明了这样做的好处。“
    来至cocoa,这个说法应该挺有道理。
    因为我们知道button却是存在一个highlighted实例变量.因此为何上面我们只是add一个相关的keypath就行了,
    可以按照kvc查找的逻辑理解,就说的过去了。

    16. oc中可修改和不可以修改类型。

    答:可修改不可修改的集合类。这个我个人简单理解就是可动态添加修改和不可动态添加修改一样。
    比如NSArray和NSMutableArray。前者在初始化后的内存控件就是固定不可变的,后者可以添加等,可以动态申请新的内存空间。

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

    答:多态。 主要是将数据类型的确定由编译时,推迟到了运行时。
    这个问题其实浅涉及到两个概念,运行时和多态。
    简单来说,运行时机制使我们直到运行时才去决定一个对象的类别,以及调用该类别对象指定方法。

    多态:不同对象以自己的方式响应相同的消息的能力叫做多态。意思就是假设生物类(life)都用有一个相同的方法-eat;
    那人类属于生物,猪也属于生物,都继承了life后,实现各自的eat,但是调用是我们只需调用各自的eat方法。
    也就是不同的对象以自己的方式响应了相同的消息(响应了eat这个选择器)。

    18. 通知和协议的不同之处?

    答:协议有控制链(has-a)的关系,通知没有。
    首先我一开始也不太明白,什么叫控制链(专业术语了~)。但是简单分析下通知和代理的行为模式,我们大致可以有自己的理解
    简单来说,通知的话,它可以一对多,一条消息可以发送给多个消息接受者。

    代理按我们的理解,到不是直接说不能一对多,比如我们知道的明星经济代理人,很多时候一个经济人负责好几个明星的事务。
    只是对于不同明星间,代理的事物对象都是不一样的,一一对应,不可能说明天要处理A明星要一个发布会,代理人发出处理发布会的消息后,别称B的
    发布会了。但是通知就不一样,他只关心发出通知,而不关心多少接收到感兴趣要处理。

    19. frame和bounds有什么不同?

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

    20. 方法和选择器有何不同?

    答:selector是一个方法的名字,method是一个组合体,包含了名字和实现.

    21. OC的垃圾回收机制?

    答: OC2.0有Garbage collection,但是iOS平台不提供。
    一般我们了解的objective-c对于内存管理都是手动操作的,但是也有自动释放池。

    22. NSOperation queue?

    答:存放NSOperation的集合类。
    操作和操作队列,基本可以看成java中的线程和线程池的概念。用于处理ios多线程开发的问题。
    网上部分资料提到一点是,虽然是queue,但是却并不是带有队列的概念,放入的操作并非是按照严格的先进现出。
    因此对于A比B先排队取票但是B率先执行完操作,我们亦然可以感性认为这还是一个队列。
    但是后来看到一票关于这操作队列话题的文章,其中有一句提到
    “因为两个操作提交的时间间隔很近,线程池中的线程,谁先启动是不定的。”
    瞬间觉得这个queue名字有点忽悠人了,还不如pool~
    综合一点,我们知道他可以比较大的用处在于可以帮组多线程编程就好了。

    23.什么是延迟加载?

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

    24. 是否在一个视图控制器中嵌入两个tableview控制器?

    答:一个视图控制只提供了一个View视图,理论上一个tableViewController也不能放吧,
    只能说可以嵌入一个tableview视图。当然,题目本身也有歧义,如果不是我们定性思维认为的UIViewController,而是宏观的表示视图控制者,那我们倒是可以把其看成一个视图控制者,它可以控制多个视图控制器,比如TabbarController那样的感觉。

    25.一个tableView是否可以关联两个不同的数据源?你会怎么处理?

    答:首先我们从代码来看,数据源如何关联上的,其实是在数据源关联的代理方法里实现的。
    因此我们并不关心如何去关联他,他怎么关联上,方法只是让我返回根据自己的需要去设置如相关的数据源。
    因此,我觉得可以设置多个数据源啊,但是有个问题是,你这是想干嘛呢?想让列表如何显示,不同的数据源分区块显示?

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

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

    27.在应用中可以创建多少autorelease对象,是否有限制?

    答案:无

    28. 如果我们不创建内存池,是否有内存池提供给我们?

    答:界面线程维护着自己的内存池,用户自己创建的数据线程,则需要创建该线程的内存池

    29. 什么时候需要在程序中创建内存池?

    答:用户自己创建的数据线程,则需要创建该线程的内存池

    30. 类NSObject的那些方法经常被使用?

    答:NSObject是Objetive-C的基类,其由NSObject类及一系列协议构成。
    其中类方法alloc、class、 description 对象方法init、dealloc、– performSelector:withObject:afterDelay:等经常被使用

    31.什么是简便构造方法?

    答:简便构造方法一般由CocoaTouch框架提供,如NSNumber的 + numberWithBool: + numberWithChar: + numberWithDouble: + numberWithFloat: + numberWithInt:
    Foundation下大部分类均有简便构造方法,我们可以通过简便构造方法,获得系统给我们创建好的对象,并且不需要手动释放。

    32. 如何使用Xcode设计通用应用?

    答:使用MVC模式设计应用,其中Model层完成脱离界面,即在Model层,其是可运行在任何设备上,在controller层,根据iPhone与iPad(独有UISplitViewController)的不同特点选择不同的viewController对象。在View层,可根据现实要求,来设计,其中以xib文件设计时,其设置其为universal。

    33.UIView的动画效果有那些?

    答:有很多,如 UIViewAnimationOptionCurveEaseInOut UIViewAnimationOptionCurveEaseIn UIViewAnimationOptionCurveEaseOut UIViewAnimationOptionTransitionFlipFromLeft UIViewAnimationOptionTransitionFlipFromRight UIViewAnimationOptionTransitionCurlUpUIViewAnimationOptionTransitionCurlDown

    34. 在iPhone应用中如何保存数据?

    答:有以下几种保存机制:
    1).通过web服务,保存在服务器上
    2).通过NSCoder固化机制,将对象保存在文件中
    3).通过SQlite或CoreData保存在文件数据库中

    35. 什么是coredata?

    答:coredata是苹果提供一套数据保存框架,其基于SQlite

    36. 什么是NSManagedObject模型?

    答:NSManagedObject是NSObject的子类 ,也是coredata的重要组成部分,它是一个通用的类,实现了core data 模型层所需的基本功能,用户可通过子类化NSManagedObject,建立自己的数据模型。

    37. 什么是NSManagedobjectContext?

    答:NSManagedobjectContext对象负责应用和数据库之间的交互。

    38.什么是谓词?

    答:谓词是通过NSPredicate,是通过给定的逻辑条件作为约束条件,完成对数据的筛选。
    predicate = [NSPredicate predicateWithFormat:@"customerID == %d",n];
    a = [customers filteredArrayUsingPredicate:predicate];

    39.谈谈对Block 的理解?并写出一个使用Block执行UIVew动画?

    答:Block是可以获取其他函数局部变量的匿名函数,其不但方便开发,并且可以大幅提高应用的执行效率(多核心CPU可直接处理Block指令)
    [UIView transitionWithView:self.view
    duration:0.2
    options:UIViewAnimationOptionTransitionFlipFromLeft
    animations:^{ [[blueViewController view] removeFromSuperview]; [[self view] insertSubview:yellowViewController.view atIndex:0]; }
    completion:NULL];

    40. 写出上面代码的Block的定义。

    答:
    typedef void(^animations) (void);
    typedef void(^completion) (BOOL finished);

    41.iOS 中的多线程

    答: iOS中的多线程,是Cocoa框架下的多线程,通过Cocoa的封装,可以让我们更为方便的使用线程,做过C++的同学可能会对线程有更多的理解,比如线程的创立,信号量、共享变量有认识,Cocoa框架下会方便很多,它对线程做了封装,有些封装,可以让我们创建的对象,本身便拥有线程,也就是线程的对象化抽象,从而减少我们的工程,提供程序的健壮性。

    GCD是(Grand Central Dispatch)的缩写 ,从系统级别提供的一个易用地多线程类库,具有运行时的特点,能充分利用多核心硬件。GCD的API接口为C语言的函数,函数参数中多数有Block,关于Block的使用参看这里,为我们提供强大的“接口”,对于GCD的使用参见本文

    NSOperation与Queue
    NSOperation是一个抽象类,它封装了线程的细节实现,我们可以通过子类化该对象,加上NSQueue来同面向对象的思维,管理多线程程序。具体可参看这里:一个基于NSOperation的多线程网络访问的项目。

    NSThread
    NSThread是一个控制线程执行的对象,它不如NSOperation抽象,通过它我们可以方便的得到一个线程,并控制它。但NSThread的线程之间的并发控制,是需要我们自己来控制的,可以通过NSCondition实现。

    42.在项目什么时候选择使用GCD,什么时候选择NSOperation?

    答: 项目中使用NSOperation的优点是NSOperation是对线程的高度抽象,在项目中使用它,会使项目的程序结构更好,子类化NSOperation的设计思路,是具有面向对象的优点(复用、封装),使得实现是多线程支持,而接口简单,建议在复杂项目中使用。

    项目中使用GCD的优点是GCD本身非常简单、易用,对于不复杂的多线程操作,会节省代码量,而Block参数的使用,会是代码更为易读,建议在简单项目中使用。

    43.什么是block

    答: 对于闭包(block),有很多定义,其中闭包就是能够读取其它函数内部变量的函数,这个定义即接近本质又较好理解。对于刚接触Block的同学,会觉得有些绕,因为我们习惯写这样的程序main(){ funA();} funA(){funB();} funB(){…..}; 就是函数main调用函数A,函数A调用函数B… 函数们依次顺序执行,但现实中不全是这样的,例如项目经理M,手下有3个程序员A、B、C,当他给程序员A安排实现功能F1时,他并不等着A完成之后,再去安排B去实现F2,而是安排给A功能F1,B功能F2,C功能F3,然后可能去写技术文档,而当A遇到问题时,他会来找项目经理M,当B做完时,会通知M,这就是一个异步执行的例子。在这种情形下,Block便可大显身手,因为在项目经理M,给A安排工作时,同时会告诉A若果遇到困难,如何能找到他报告问题(例如打他手机号),这就是项目经理M给A的一个回调接口,要回掉的操作,比如接到电话,百度查询后,返回网页内容给A,这就是一个Block,在M交待工作时,已经定义好,并且取得了F1的任务号(局部变量),却是在当A遇到问题时,才调用执行,跨函数在项目经理M查询百度,获得结果后回调该block。

    44.block 实现原理

    答: Objective-C是对C语言的扩展,block的实现是基于指针和函数指针。
    从计算语言的发展,最早的goto,高级语言的指针,到面向对象语言的block,从机器的思维,一步步接近人的思维,以方便开发人员更为高效、直接的描述出现实的逻辑(需求)。
    使用实例
    cocoaTouch框架下动画效果的Block的调用
    使用typed声明block
    typedef void(^didFinishBlock) (NSObject *ob);
    这就声明了一个didFinishBlock类型的block,
    然后便可用
    @property (nonatomic,copy) didFinishBlock finishBlock;
    声明一个blokc对象,注意对象属性设置为copy,接到block 参数时,便会自动复制一份。
    __block是一种特殊类型,
    使用该关键字声明的局部变量,可以被block所改变,并且其在原函数中的值会被改变。

    45.关于block

    1). 使用block和使用delegate完成委托模式有什么优点?
    首先要了解什么是委托模式,委托模式在iOS中大量应用,其在设计模式中是适配器模式中的对象适配器,Objective-C中使用id类型指向一切对象,使委托模式更为简洁。了解委托模式的细节:
    iOS设计模式—-委托模式
    使用block实现委托模式,其优点是回调的block代码块定义在委托对象函数内部,使代码更为紧凑;
    适配对象不再需要实现具体某个protocol,代码更为简洁。

    2). 多线程与block
    GCD与Block
    使用 dispatch_async 系列方法,可以以指定的方式执行block
    GCD编程实例
    dispatch_async的完整定义
    void dispatch_async(
    dispatch_queue_t queue,
    dispatch_block_t block);
    功能:在指定的队列里提交一个异步执行的block,不阻塞当前线程
    通过queue来控制block执行的线程。主线程执行前文定义的 finishBlock对象
    dispatch_async(dispatch_get_main_queue(),^(void){finishBlock();});

    46.谈谈Object-C的内存管理方式及过程?

    答: 1).当你使用new,alloc和copy方法创建一个对象时,该对象的保留计数器值为1.当你不再使用该对象时,你要负责向该对象发送一条release或autorelease消息.这样,该对象将在使用寿命结束时被销毁.
    2).当你通过任何其他方法获得一个对象时,则假设该对象的保留计数器值为1,而且已经被设置为自动释放,你不需要执行任何操作来确保该对象被清理.如果你打算在一段时间内拥有该对象,则需要保留它并确保在操作完成时释放它.
    3).如果你保留了某个对象,你需要(最终)释放或自动释放该对象.必须保持retain方法和release方法的使用次数相等.

    47.Object-C有私有方法吗?私有变量呢?

    答: objective-c – 类里面的方法只有两种, 静态方法和实例方法. 这似乎就不是完整的面向对象了,按照OO的原则就是一个对象只暴露有用的东西. 如果没有了私有方法的话, 对于一些小范围的代码重用就不那么顺手了. 在类里面声名一个私有方法
    在Objective‐C中,所有实例变量默认都是私有的,所有实例方法默认都是公有的

    48.Object-C有多继承吗?没有的话用什么代替?cocoa 中所有的类都是NSObject 的子类

    答: 多继承在这里是用protocol 委托代理 来实现的
    你不用去考虑繁琐的多继承 ,虚基类的概念.
    ood的多态特性 在 obj-c 中通过委托来实现.

    49.内存管理 Autorelease、retain、copy、assign的set方法和含义?

    答: 1).你初始化(alloc/init)的对象,你需要释放(release)它。例如:
    NSMutableArray aArray = [[NSArray alloc] init]; 后,需要 [aArray release];
    2).你retain或copy的,你需要释放它。例如:
    [aArray retain] 后,需要 [aArray release];
    3).被传递(assign)的对象,你需要斟酌的retain和release。例如:
    obj2 = [[obj1 someMethod] autorelease];

    对象2接收对象1的一个自动释放的值,或传递一个基本数据类型(NSInteger,NSString)时:你或希望将对象2进行retain,以防止它在被使用之前就被自动释放掉。但是在retain后,一定要在适当的时候进行释放。
    关于索引计数(Reference Counting)的问题
    retain值 = 索引计数(Reference Counting)
    NSArray对象会retain(retain值加一)任何数组中的对象。当NSArray被卸载(dealloc)的时候,所有数组中的对象会 被 执行一次释放(retain值减一)。不仅仅是NSArray,任何收集类(Collection Classes)都执行类似操作。例如 NSDictionary,甚至UINavigationController。
    Alloc/init建立的对象,索引计数为1。无需将其再次retain。
    [NSArray array]和[NSDate date]等“方法”建立一个索引计数为1的对象,但是也是一个自动释放对象。所以是本地临时对象,那么无所谓了。如果是打算在全Class中使用的变量(iVar),则必须retain它。
    缺省的类方法返回值都被执行了“自动释放”方法。(如上中的NSArray)
    在类中的卸载方法“dealloc”中,release所有未被平衡的NS对象。(
    所有未被autorelease,而retain值为1的)

    50. 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

    相关文章

      网友评论

        本文标题:iOS问答 - 1

        本文链接:https://www.haomeiwen.com/subject/xpovyxtx.html