ios知识整理 (未完成)
ios知识整理 (未完成)
小胖123 发表于1年前
ios知识整理 (未完成)
  • 发表于 1年前
  • 阅读 22
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 新注册用户 域名抢购1元起>>>   

###简述OC中内存管理机制。 使用了一种叫做引用计数的机制来管理内存中的对象。OC中每个对象都对应着他们自己的引用计数,引用计数可以理解为一个整数计数器,当使用alloc方法创建对象的时候,持有计数会自动设置为1。当你向一个对象发送retain消息 时,持有计数数值会增加1。相反,当你像一个对象发送release消息时,持有计数数值会减小1。当对象的持有计数变为0的时候,对象会释放自己所占用的内存。

retain(引用计数加1)->release(引用计数减1)

alloc(申请内存空间)->dealloc(释放内存空间)

readwrite: 表示既有getter,也有setter (默认)

readonly: 表示只有getter,没有setter

nonatomic:不考虑线程安全

atomic:线程操作安全 (默认)

线程安全情况下的setter和getter:

`

  • (NSString*) value {
    @synchronized(self) {
    return [[_value retain] autorelease];
    }} `

-(void) setValue:(NSString*)aValue { @synchronized(self) { [aValue retain]; [_value release]; _value = aValue; } }

retain: release旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1

assign: 简单赋值,不更改索引计数 (默认)

copy: 其实是建立了一个相同的对象,地址不同(retain:指针拷贝 copy:内容拷贝)

strong:(ARC下的)和(MRC)retain一样 (默认)

weak:(ARC下的)和(MRC)assign一样, weak当指向的内存释放掉后自动nil化,防止野指针

unsafe_unretained 声明一个弱应用,但是不会自动nil化,也就是说,如果所指向的内存区域被释放了,这个指针就是一个野指针了。


autoreleasing 用来修饰一个函数的参数,这个参数会在函数返回的时候被自动释放。

###类变量的@protected ,@private,@public,@package,声明各有什么含义? @private: 作用范围只能在自身类

@protected:作用范围在自身类和继承自己的子类 (默认)

@public:作用范围最大,可以在任何地方被访问。

@package:这个类型最常用于框架类的实例变量,同一包内能用,跨包就不能访问

###线程是什么?进程是什么?二者有什么区别和联系? 一个程序至少有一个进程,一个进程至少有一个线程: 进程:一个程序的一次运行,在执行过程中拥有独立的内存单元,而多个线程共享一块内存 线程:线程是指进程内的一个执行单元。 联系:线程是进程的基本组成单位 ####区别 (1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位


(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行


(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源. 
(4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。 举例说明:操作系统有多个软件在运行(QQ、office、音乐等),这些都是一个个进程,而每个进程里又有好多线程(比如QQ,你可以同时聊天,发送文件等)

###谈谈你对多线程开发的理解?ios中有几种实现多线程的方法? 好处: 1.使用线程可以把占据时间长的程序中的任务放到后台去处理 2.用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度 3.程序的运行速度可能加快 4·在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。 缺点: 1.如果有大量的线程,会影响性能,因为操作系统需要在它们之间切换。 2.更多的线程需要更多的内存空间。 3.线程的中止需要考虑其对程序运行的影响。 4.通常块模型数据是在多个线程间共享的,需要防止线程死锁情况的发生。 实现多线程的方法: NSObject类方法 NSThread NSOperation GCD

###假设有一个字符串aabcad,请写一段程序,去掉字符串中不相邻的重复字符串,即上述字符串处理之后的输出结果为:aabcd

NSMutableString * str = [[NSMutableString alloc]initWithFormat;@“aabcad”]; for (int i = 0 ,i < str.length - 1 ;i++){ unsigned char a = [str characterAtIndex:i]; for (int j = i + 1 ,j < str.length ,j++){ unsigned char b = [str characterAtIndex:j]; if (a == b ){ if (j == i + 1){ }else{ [str deleteCharactersInRange:NSMakeRange(j, 1)]; } } } } NSLog(@“%@”,str);

###iOS类是否可以多继承?如果没有,那可以用其他方法实现吗?简述实现过程。 不可以多继承 多继承在这里是用protocol 委托代理来实现的
 ,ood的多态特性在obj-c中通过委托来实现。

###堆和栈的区别? 堆需要用户手动释放内存,而栈则是编译器自动释放内存 问题扩展:要知道OC中NSString的内存存储方式

生成一个NSString类型的字符串有三种方法:

方法1.直接赋值: NSString *str1 = @"my string";

方法2.类函数初始化生成: NSString *str2 = [NSString stringWithString:@"my string"];

方法3.实例方法初始化生成:  NSString *str3 = [[NSString alloc] initWithString:@"my string"];

              NSString *str4 = [[NSString alloc]initWithFormat:@"my string"];

区别1: 方法一生成字符串时,不会初始化内存空间,所以使用结束后不会释放内存;

   而其他三个都会初始化内存空间,使用结束后要释放内存;

   在释放内存时方法2和3也不同,方法2是autorelease类型,内存由系统释放;方法3则必须手动释放

区别2:用Format初始化的字符串,需要初始化一段动态内存空间,如:0x6a42a40;

   而用String声明的字符串,初始化的是常量内存区,如:0x46a8,常量内存区的地址,只要值相同,占用的地址空间是一致的。

   所以str3和str1的地址一致,但是str4和str1的地址不一致。

###iOS本地数据存储都有哪几种方式? NSKeyedArchiver
NSUserDefaults Write写入方式 SQLite3 http://blog.csdn.net/tianyitianyi1/article/details/7713103<br /> (问题扩展:什么情况下使用什么样的数据存储)

1.NSKeyedArchiver:采用归档的形式来保存数据,数据对象需要遵守NSCoding协议,对象对应的类必须提供encodeWithCoder:和initWithCoder:方法。缺点:只能一次性归档保存以及一次性解压。所以只能针对小量数据,对数据操作比较笨拙,如果想改动数据的某一小部分,需要解压或归档整个数据。

2.NSUserDefaults:用来保存应用程序设置和属性、用户保存的数据。用户再次打开程序或开机后这些数据仍然存在。NSUserDefaults可以存储的数据类型包括:NSData、NSString、NSNumber、NSDate、NSArray、NSDictionary。缺点:如果要存储其他类型,需要转换为前面的类型,才能用NSUserDefaults存储。

3.Write写入方式:永久保存在磁盘中。第一步:获得文件即将保存的路径:第二步:生成在该路径下的文件:第三步:往文件中写入数据:最后:从文件中读出数据:

4.SQLite:采用SQLite数据库来存储数据。SQLite作为一中小型数据库,应用ios中,跟前三种保存方式相比,相对比较复杂一些。

###Objective-C的类可以多重继承么?可以采用多个协议么?

答:不可以多重继承,可以采用多个协议。

import和#include的区别是什么?#import<> 跟 #import""有什么区别?

#import能避免头文件被重复包含的问题:

1) 一般来说,导入objective c的头文件时用#import,包含c/c++头文件时用#include。

使用include要注意重复引用的问题:

class A,class B都引用了class C,class D若引用class A与class B,就会报重复引用的错误。

2)#import 确定一个文件只能被导入一次,这使你在递归包含中不会出现问题。

所以,#import比起#include的好处就是它避免了重复引用的问题。所以在OC中我们基本用的都是import。

#import<> 包含iOS框架类库里的类,#import""包含项目里自定义的类。

###Category是什么?扩展一个类的方式用继承好还是类目好?为什么?

答:Category是类目。用类目好,因为继承要满足a is a b的关系,而类目只需要满足a has a b的关系,局限性更小,你不用定义子类就能扩展一个类的功能,还能将类的定义分开放在不同的源文件里, 用Category去重写类的方法,仅对本Category有效,不会影响到其他类与原有类的关系。 Category是Objective-C中常用的语法特性,通过它可以很方便的为已有的类来添加函数。但是Category不允许为已有的类添加新的属性或者成员变量。
一种常见的办法是通过runtime.h中objc_getAssociatedObject / objc_setAssociatedObject来访问和生成关联对象。通过这种方法来模拟生成属性。

@interface NSObject (IndieBandName) @property (nonatomic, strong) NSString *indieBandName; @end

// NSObject+IndieBandName.m #import "NSObject+Extension.h" #import &lt;objc/runtime.h&gt; static const void *IndieBandNameKey = &IndieBandNameKey; @implementation NSObject (IndieBandName) @dynamic indieBandName;

- (NSString *)indieBandName { return objc_getAssociatedObject(self, IndieBandNameKey); }

- (void)setIndieBandName:(NSString *)indieBandName{ objc_setAssociatedObject(self, IndieBandNameKey, indieBandName, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } @end

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

Ø 没有 * 号

Ø 动态数据类型

Ø 可以指向任何类的对象(设置是nil),而不关心其具体类型

Ø 在运行时检查其具体类型

Ø 可以对其发送任何(存在的)消息

###7、委托是什么?委托和委托方双方的property声明用什么属性?为什么?

委托:一个对象保存另外一个对象的引用,被引用的对象实现了事先确定的协议,该协议用于将引用对象中的变化通知给被引用对象。

委托和委托方双方的property声明属性都是assign而不是retain

为了避免循环引用造成的内存泄露。

  循环引用的问题这样理解:

   比如在main函数中创建了两个类的对象A和B,现在引用计数都是1。现在让A和B互相引用(A有一个属性是B对象,属性说明是retain;B有一个属性是A对象,属性说明是retain),现在两个对象的引用计数都增加了1,都变成了2。

  现在执行[A release]; [B release]; 此时创建对象的main函数已经释放了自己对对象的所有权,但是此时A和B的引用计数都还是1,因为他们互相引用了。

 这时你发现A和B将无法释放,因为要想释放A必须先释放B,在B的dealloc方法中再释放A。同理,要想释放B必须先释放A,在A的dealloc方法中再释放B。所以这两个对象将一直存在在内存中而不释放。这就是所谓的循环引用的问题。要想解决这个问题,一般的方法可以将引用的属性设置为assign,而不是retain来处理。

###浅拷贝和深拷贝区别是什么? 浅层复制:只复制指向对象的指针,而不复制引用对象本身。

深层复制:复制引用对象本身。

意思就是说我有个A对象,复制一份后得到A_copy对象后,对于浅复制来说,A和A_copy指向的是同一个内存资源,复制的只不过是是一个指针,对象本身资源还是只有一份,那如果我们对A_copy执行了修改操作,那么发现A引用的对象同样被修改,这其实违背了我们复制拷贝的一个思想。深复制就好理解了,内存中存在了两份独立对象本身。

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

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

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

###内存管理的几条原则是什么?按照默认法则,哪些关键字生成的对象需要手动释放?哪些情况下不需要手动释放,会直接进入自动释放池?

• 当使用new、alloc或copy方法创建一个对象时,该对象引用计数器为1。如果不需要使用该对象,可以向其发送release或autorelease消息,在其使用完毕时被销毁。

• 如果通过其他方法获取一个对象,则可以假设这个对象引用计数为1,并且被设置为autorelease,不需要对该对象进行清理,如果确实需要retain这个对象,则需要使用完毕后release。

• 如果retain了某个对象,需要release或autorelease该对象,保持retain方法和release方法使用次数相等。

使用new、alloc、copy关键字生成的对象和retain了的对象需要手动释放。设置为autorelease的对象不需要手动释放,会直接进入自动释放池。

###怎样实现一个单例模式的类,给出思路,不写代码。

• 首先必须创建一个全局实例,通常存放在一个全局变量中,此全局变量设置为nil

• 提供工厂方法对该全局实例进行访问,检查该变量是否为nil,如果nil就创建一个新的实例,最后返回全局实例

• 全局变量的初始化在第一次调用工厂方法时会在+allocWithZone:中进行,所以需要重写该方法,防止通过标准的alloc方式创建新的实例

• 为了防止通过copy方法得到新的实例,需要实现-copyWithZone方法

• 只需在此方法中返回本身对象即可,引用计数也不需要进行改变,因为单例模式下的对象是不允许销毁的,所以也就不用保留

• 因为全局实例不允许释放,所以retain,release,autorelease方法均需重写

###@class的作用是什么?

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

• @class的作用是告诉编译器,有这么一个类,用吧,没有问题

• @class还可以解决循环依赖的问题,例如A.h导入了B.h,而B.h导入了A.h,每一个头文件的编译都要让对象先编译成功才行

• 使用@class就可以避免这种情况的发生

###KVC是什么?KVO是什么?有什么特点?

• KVC是键值编码,特点是通过指定表示要访问的属性名字的字符串标识符,可以进行类的属性读取和设置

• KVO是键值观察,特点是利用键值观察可以注册成为一个对象的观察者,在该对象的某个属性变化时收到通知

###MVC是什么?有什么特性?

– MVC是一种设计模式,由模型、视图、控制器3部分组成。

– 模型:保存应用程序数据的类,处理业务逻辑的类

– 视图:窗口,控件和其他用户能看到的并且能交互的元素

– 控制器:将模型和试图绑定在一起,确定如何处理用户输入的类

###定义属性时,什么情况使用copy、assign、retain?

使用assign: 对基础数据类型 (NSInteger,CGFloat)和C数据类型(int, float,double, char, 等等)

使用copy: 希望获得源对象的副本而不改变源对象内容时,对NSString

使用retain: 希望获得源对象的所有权时,对其他NSObject和其子类

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

assign用于简单数据类型,如NSInteger,double,bool,

retain和copy用于对象,

readwrite是可读可写特性;需要生成getter方法和setter方法时

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

assign是赋值特性,setter方法将传入参数赋值给实例变量;仅设置变量时;

retain表示持有特性,setter方法将传入参数先保留,再赋值,传入参数的retaincount会+1;

copy表示赋值特性,setter方法将传入对象复制一份;需要完全一份新的变量时。

nonatomic非原子操作,决定编译器生成的setter getter是否是原子操作,atomic表示多线程安全,一般使用nonatomic

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

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

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

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

###Object C中创建线程的方法是什么?如果在主线程中执行代码,方法是什么?如果想延时执行代码、方法又是什么?

线程创建有三种方法:使用NSThread创建、使用 GCD的dispatch、使用子类化的NSOperation,然后将其加入NSOperationQueue;在主线程执行代码,方法是 performSelectorOnMainThread,如果想延时执行代码可以用performSelector:onThread:withObject:waitUntilDone

atomic/nonatomic的作用,@dynamic的作用?

atomic:原子性,它没有一个如果你没有对原子性进行一个声明(atomic or nonatomic),那么系统会默认你选择的是atomic。

原子性就是说一个操作不可以被中途cpu暂停然后调度, 即不能被中断, 要不就执行完, 要不就不执行. 如果一个操作是原子性的,那么在多线程环境下, 就不会出现变量被修改等奇怪的问题。原子操作就是不可再分的操作,在多线程程序中原子操作是一个非常重要的概念,它常常用来实现一些同步机制,同时也是一些常见的多线程Bug的源头。当然,原子性的变量在执行效率上要低些。

关于异步与同步:并非同步就是不好,我们通常需要同时进行多个操作,这时使用异步,而对于程序来说,一般就是使用多线程,然而我们很多时候需要在多个线程间访问共享的数据,这个时候又需要同步来保证数据的准确性或访问的先后次序。当有多个线程需要访问到同一个数据时,OC中,我们可以使用@synchronized(变量)来对该变量进行加锁(加锁的目的常常是为了同步或保证原子操作)。

nonatomic:非原子性,是直接从内存中取数值,因为它是从内存中取得数据,它并没有一个加锁的保护来用于cpu中的寄存器计算Value,它只是单纯的从内存地址中,当前的内存存储的数据结果来进行使用。在多线环境下可提高性能,但无法保证数据同步。

##OSI(Open System Interconnection)开放式系统互联参考模型 把网络协议从逻辑上分为了7层,试列举常见的应用层协议。?????

###30、网络传输层协议中,基于TCP/IP协议和UDP/IP的连接有什么区别?

TCP:TransmissionControl Protocol 传输控制协议TCP是一种面向连接(连接导向)的、可靠的、基于字节流的运输层(Transport layer)通信协议,由IETF的RFC 793说明(specified)。

UDP 是User DatagramProtocol的简称, 中文名是用户数据包协议,是OSI 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768是UDP的正式规范。

面向连接:是指通信双方在通信时,要事先建立一条通信线路,其有三个过程:建立连接、使用连接和释放连接。电话系统是一个面向连接的模式,拨号、通话、挂机;TCP协议就是一种面向连接的协议。

面向无连接:是指通信双方不需要事先建立一条通信线路,而是把每个带有目的地址的包(报文分组)送到线路上,由系统自主选定路线进行传输。邮政系统是一个无连接的模式,天罗地网式的选择路线,天女散花式的传播形式;IP、UDP协议就是一种无连接协议。

###iOS中有哪些回调机制,并作简单的比较。

各种回调机制的比较:

1)目标动作对:当两个对象之间有比较紧密的关系时,如视图控制器与其下的某个视图。

2)代理:也叫委托,当某个对象收到多个事件,并要求同一个对象来处理所有事件时。委托机制依赖于某个协议定义的方法来发送消息。

3)通告机制:当需要多个对象或两个无关对象处理同一个事件时。

4)Block:适用于回调只发生一次的简单任务。

###34、列出在编码中哪些编码习惯有助于提高代码质量、软件性能和健壮性,减少程序崩溃。

#使用严格的命名规则(如匈牙利命名法)能够避免不必要的类型转换错误。

#在编码前先设计好流程图或使用伪代码,清晰化整个设计意图。

#对自己的代码进行严格的单元测试(unit testing)。

单元测试是指对软件中的最小可测试单元进行检查和验证。如C语言中单元指一个函数,Java里单元指一个类,图形化的软件中可以指一个窗口或一个菜单等。总的来说,单元就是人为规定的最小的被测功能模块。单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。

#异常的处理

首先不要轻易使用异常的捕获,其次要尽可能捕获具体的异常。对于异常的处理最好能够采用封装的方式,大家统一使用。这样可以保证异常处理的一致性也可以保证当异常出现时性能的稳定。

使用内省的方法检查方法的输入

#采用增量式的编程方式。

采用增量式编程和测试,会倾向于创建更小的方法和更具内聚性的类。你应该经常评估代码质量,并不时的进行许多小调整,而不是一次修改许多东西。在写了几行代码之后,就应该进行一次构建/测试。在没有得到反馈时,你不要走的太远。

#使用工具(如Instrument)来帮助检查内存泄漏、过早释放内存、CPU使用效率等问题。

#消除所有的编译警告,警告就是错误。

#写防御性的代码,使用内省的方法检查传入的参数。 ###objective c中有私有方法和私有变量吗 objective c中既有私有方法,也有私有变量。 先说私有方法, 由于Objective-C的动态消息传递机制,OC中不存在真正意义上的私有方法。 但是如果你不在.h文件中声明,只在.m文件中实现,或在.m文件的Class Extension里声明,那么基本上和私有方法差不多。

至于私有变量是可以通过@private来声明的,例如: @interface Sample : NSObject{ @private NSString *tteesstt; } @property (nonatomic,strong) NSString *hoge;

  • (void)foo; @end 则tteesstt变量是私有的。而属性hoge是默认公有。

现在Apple官方文档里是用property比较多,直接定义instance variable少。将property定义到.m的Class Extension也基本上和私有变量差不多。

简而言之,将你希望公有的放到.h文件,私有的放到.m文件。在import时只import .h文件(.m文件也是可以import的,但是我们一般不这么做。

###堆和栈的区别?

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

申请大小:栈:栈是向低地址扩展的数据结构,是一块连续的内存的区域

               堆:是向高地址扩展的数据结构,是不连续的内存区域。

分配方式:堆都是动态分配的 ,动态分配由alloca函数进行分配

               栈的动态分配由编译器进行释放,无需我们手工实现 

##C语言 44. main()

{ int a[5]={1,2,3,4,5};

int *ptr=(int *)(&a+1);

printf("%d,%d",(a+1),(ptr-1));

}

答:2,5 (a+1)就是a[1],(ptr-1)就是a[4],执行结果是2,5   

&a+1不是首地址+1,系统会认为加一个a数组的偏移,是偏移了一个数组的大小(本例是5个int)   

int *ptr=(int *)(&a+1);则ptr实际是&(a[5]),也就是a+5

原因如下:&a是数组指针,其类型为 int (*)[5];

而指针加1要根据指针类型加上一定的值,不同类型的指针+1之后增加的大小不同。  

a是长度为5的int数组指针,所以要加 5*sizeof(int),所以ptr实际是a[5],

但是prt与(&a+1)类型是不一样的(这点很重要),所以prt-1只会减去sizeof(int*)  

a,&a的地址是一样的,但意思不一样    

a是数组首地址,也就是a[0]的地址,&a是对象(数组)首地址,         a+1是数组下一元素的地址,即a[1],&a+1是下一个对象的地址,即a[5].

###关键字const有什么含义?

我只要一听到被面试者说:"const意味着常数"(不是常数,可以是变量,只是你不能修改它),我就知道我正在和一个业余者打交道。去年Dan Saks已经在他的文章里完全概括了const的所有用法,因此ESP(译者:Embedded Systems Programming)的每一位读者应该非常熟悉const能做什么和不能做什么.如果你从没有读到那篇文章,只要能说出const意味着"只读"就可以了。尽管这个答案不是完全的答案,但我接受它作为一个正确的答案。(如果你想知道更详细的答案,仔细读一下Saks的文章吧。) 如果应试者能正确回答这个问题,我将问他一个附加的问题:下面的声明都是什么意思? Const只是一个修饰符,不管怎么样a仍然是一个int型的变量 const int a; int const a; const int *a; int * const a; int const * a const; 本质:const在谁后面谁就不可修改,const在最前面则将其后移一位即可,二者等效

前两个的作用是一样,a是一个常整型数。第三个意味着a是一个指向常整型数的指针(也就是,指向的整型数是不可修改的,但指针可以,此最常见于函数的参数,当你只引用传进来指针所指向的值时应该加上const修饰符,程序中修改编译就不通过,可以减少程序的bug)。

第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。

如果应试者能正确回答这些问题,那么他就给我留下了一个好印象。顺带提一句,也许你可能会问,即使不用关键字 ,也还是能很容易写出功能正确的程序,那么我为什么还要如此看重关键字const呢?我也如下的几下理由:

  1. 关键字const的作用是为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的。如果你曾花很多时间清理其它人留下的垃圾,你就会很快学会感谢这点多余的信息。(当然,懂得用const的程序员很少会留下的垃圾让别人来清理的。)
  2. 通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。
  3. 合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug的出现。

const关键字至少有下列n个作用: (1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了; (2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const; (3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值; (4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量; (5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。例如: const classA operator*(const classA& a1,const classA& a2);   operator的返回结果必须是一个const对象。如果不是,这样的变态代码也不会编译出错: classA a, b, c; (a * b) = c; // 对ab的结果赋值   操作(a * b) = c显然不符合编程者的初衷,也没有任何意义。

###extern "C"的惯用法

extern可置于变量或者函数前,以表示变量或者函数的定义在别的文件中,提示编译器遇到此变量或函数时,在其它模块中寻找其定义。

###48.为什么标准头文件都有类似以下的结构?

#ifndef __INCvxWorksh

#define __INCvxWorksh

#ifdef __cplusplus   

extern "C" {    

 #endif     /*...*/   

  #ifdef __cplusplus    

  }   

#endif

#endif /* __INCvxWorksh */

显然,头文件中的编译宏“#ifndef __INCvxWorksh、#define __INCvxWorksh、#endif” 的作用是防止该头文件被重复引用。

###51.列举几种进程的同步机制,并比较其优缺点。

答案:原子操作、信号量机制、自旋锁、管程、会合、分布式系统

进程之间通信的途径

答案:共享存储系统消息传递系统管道:以文件系统为基础

进程死锁的原因

答案:资源竞争及进程推进顺序非法

死锁的4个必要条件

答案:互斥、请求保持、不可剥夺、环路

死锁的处理

答案:鸵鸟策略、预防策略、避免策略、检测与解除死锁

###52.什么是键-值,键路径是什么

答:模型的性质是通过一个简单的键(通常是个字符串)来指定的。视图和控制器通过键来查找相应的属性值。在一个给定的实体中,同一个属性的所有值具有相同的数据类型。键-值编码技术用于进行这样的查找—它是一种间接访问对象属性的机制。

键路径是一个由用点作分隔符的键组成的字符串,用于指定一个连接在一起的对象性质序列。第一个键的性质是由先前的性质决定的,接下来每个键的值也是相对于其前面的性质。键路径使您可以以独立于模型实现的方式指定相关对象的性质。通过键路径,您可以指定对象图中的一个任意深度的路径,使其指向相关对象的特定属性。

##55. cocoa touch框架

这些框架包括:

Core Animation

通过Core Animation,您就可以通过一个基于组合独立图层的简单的编程模型来创建丰富的用户体验。

Core Audio

Core Audio是播放,处理和录制音频的专业技术,能够轻松为您的应用程序添加强大的音频功能。

Core Data提供了一个面向对象的数据管理解决方案,它易于使用和理解,甚至可处理任何应用或大或小的数据模型。

功能列表:框架分类

下面是 Cocoa Touch 中一小部分可用的框架:

 音频和视频

   CoreAudio

   OpenAL

   MediaLibrary

   AVFoundation

 数据管理

   Core Data

   SQLite

 图形和动画

   CoreAnimation

   OpenGL ES

   Quartz 2D

  网络/li>

    Bonjour

    WebKit

    BSDSockets

  用户应用

    AddressBook

    CoreLocation

    MapKit

    StoreKit

###.类工厂方法是什么?

答:类工厂方法的实现是为了向客户提供方便,它们将分配和初始化合在一个步骤中,返回被创建的对象,并进行自动释放处理。这些方法的形式是+ (type)className...(其中 className不包括任何前缀)。工厂方法可能不仅仅为了方便使用。它们不但可以将分配和初始化合在一起,还可以为初始化过程提供对象的分配信息。类工厂方法的另一个目的是使类(比如NSWorkspace)提供单件实例。虽然init...方法可以确认一 个类在每次程序运行过程只存在一个实例,但它需要首先分配一个“生的”实例,然后还必须释放该实例。工厂方法则可以避免为可能没有用的对象盲目分配内存。

###62.sprintf,strcpy,memcpy使用上有什么要注意的地方?

答:strcpy是一个字符串拷贝的函数,它的函数原型为strcpy(char *dst, const char *src);将src开始的一段字符串拷贝到dst开始的内存中去,结束的标志符号为'\0',由于拷贝的长度不是由我们自己控制的,所以这个字符串拷贝很容易出错。

具备字符串拷贝功能的函数有memcpy,这是一个内存拷贝函数,它的函数原型为memcpy(char dst,const char src, unsigned int len);将长度为len的一段内存,从src拷贝到dst中去,这个函数的长度可控。但是会有内存叠加的问题。

sprintf是格式化函数。将一段数据通过特定的格式,格式化到一个字符串缓冲区中去。sprintf格式化的函数的长度不可控,有可能格式化后的字符串会超出缓冲区的大小,造成溢出。

iOS整体架构

MVC MVVM MVP(这个暂时不懂) <http://www.cocoachina.com/ios/20151223/14768.html>

核心动画

<http://blog.csdn.net/smking/article/details/8424851> ###Workspace <http://www.jianshu.com/p/b6c59d8ed2c9>

###iOS网络协议----HTTP/TCP/IP浅析 <http://www.codes51.com/article/detail_160050.html>

###NSThread,NSOperation,GCD区别 <http://blog.csdn.net/lgm252008/article/details/40039445>

###JSpatch实现原理 ###Cocoapods <http://www.cocoachina.com/ios/20150228/11206.html>

Cocoapods创建私有podspec 创建并设置一个私有的Spec Repo。 创建Pod的所需要的项目工程文件,并且有可访问的项目版本控制地址。 创建Pod所对应的podspec文件。 本地测试配置好的podspec文件是否可用。 向私有的Spec Repo中提交podspec。 在个人项目中的Podfile中增加刚刚制作的好的Pod并使用。 更新维护podspec。

RunLoop

共有 人打赏支持
粉丝 0
博文 5
码字总数 13161
×
小胖123
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: