iOS 笔试题

转:http://blog.sina.com.cn/s/blog_b0c5954101014upb.htmlhtml

 

1.截取字符串”20|http://www.621life.com“ 中 ‘|’字符前面及后面的数据,分别输出它们java

NSRange range = [responseString rangeOfString:@"|"];
int location = range.location;
NSString *str1 = [responseString substringToIndex:location];
NSString *str2 = [responseString substringFromIndex:location+1];

2.获取项目根路径,并在其下建立一个名称为userData的目录。程序员

// 路径
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    
    NSString *documentsDirectory = [paths firstObject];
    
    NSFileManager *fileManager = [[NSFileManager alloc]init];
    
    NSString *userDataPath = [NSString stringWithFormat:@"%@/userData",documentsDirectory];
    if (![fileManager fileExistsAtPath:userDataPath]) {
        [fileManager createDirectoryAtPath:userDataPath withIntermediateDirectories:false attributes:nil error:nil];
    }

3.在一个对象的方法里面:self.name = “object”;和name =”object”有什么不一样吗?算法

self.name = “object”会调用对象的setName()方法,
name = “object”会直接把object赋值给当前对象的name 属性。
而且 self.name 这样retainCount会加1,而name就不会。
json

4.定义属性时,什么状况使用copy,assign,和retain数组

assign用于简单数据类型,如NSInteger,double,bool,retain 和copy用户对象;xcode

copy用于当 a指向一个对象,b也想指向一样的对象的时候,若是用assign,a若是释放,再调用b会crash,若是用copy 的方式,a和b各自有本身的内存,就能够解决这个问题。服务器

retain 会使计数器加一,也能够解决assign的问题。网络

另外:tomic和nonatomic用来决定编译器生成的getter和setter是否为原子操做。在多线程环境下,原子操做是必要的,不然有可能引发错误的结果。多线程

5.关键字const有什么含意?修饰类呢?static的做用,用于类呢?还有extern c的做用

前两个的做用是同样,a是一个常整型数。

第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针能够)。

第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是能够修改的,但指针是不可修改的)。

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

结论:

 关键字const的做用是为给读你代码的人传达很是有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的。

 若是你曾花不少时间清理其它人留下的垃圾,你就会很快学会感谢这点多余的信息。(固然,懂得用const的程序员不多会留下的垃圾让

 别人 来清理的。)   经过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。  


 合理地使用关键字const可使编译器很天然地保护那些不但愿被改变的参数,防止其被无心的代码修改。简而言之,这样能够减小bug

 的出  现。  
 

(1)欲阻止一个变量被改变,可使用 const 关键字。在定义该 const 变量时,一般须要对它进行初
始化,由于之后就没有机会再去改变它了;
(2)对指针来讲,能够指定指针自己为 const,也能够指定指针所指的数据为 const,或两者同时指
定为 const;
(3)在一个函数声明中,const 能够修饰形参,代表它是一个输入参数,在函数内部不能改变其值;
(4)对于类的成员函数,若指定其为 const 类型,则代表其是一个常函数,不能修改类的成员变量;
(5)对于类的成员函数,有时候必须指定其返回值为 const 类型,以使得其返回值不为“左值”。

关键字volatile有什么含意?并给出三个不一样的例子。

一个定义为 volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。

精确地说就是,优化器在用到这个变量时必须每次都当心地从新读取这个变量的值,而不是使用保存在寄存器里的备份。

下面是volatile变量的几个例子:

并行设备的硬件寄存器(如:状态寄存器)  
 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)  
 多线程应用中被几个任务共享的变量


 一个参数既能够是const还能够是volatile吗?解释为何。  
 一个指针能够是volatile 吗?解释为何。

下面是答案:  
 是的。一个例子是只读的状态寄存器。它是volatile由于它可能被意想不到地改变。它是const由于程序不该该试图去修改它。  
 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。

6. static 关键字的做用:

(1)函数体内 static 变量的做用范围为该函数体,不一样于 auto 变量,该变量的内存只被分配一次,
所以其值在下次调用时仍维持上次的值;
(2)在模块内的 static 全局变量能够被模块内所用函数访问,但不能被模块外其它函数访问;
(3)在模块内的 static 函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明
它的模块内;
(4)在类中的 static 成员变量属于整个类所拥有,对类的全部对象只有一份拷贝;
(5)在类中的 static 成员函数属于整个类所拥有,这个函数不接收 this 指针,于是只能访问类的static 成员变量。

 extern "C" 的做用

(1)被 extern "C"限定的函数或变量是 extern 类型的;
     extern 是 C/C++语言中代表函数和全局变量做用范围(可见性)的关键字,该关键字告诉编译器,
     其声明的函数和变量能够在本模块或其它模块中使用。

(2)被 extern "C"修饰的变量和函数是按照 C 语言方式编译和链接的;
 extern "C"的惯用法

(1)在 C++中引用 C 语言中的函数和变量,在包含 C 语言头文件(假设为 cExample.h)时,需进
       行下列处理:
  extern "C"  {  
   #include "cExample.h"  
  }  
而在 C 语言的头文件中,对其外部函数只能指定为 extern 类型,C 语言中不支持 extern "C"声明,
在.c 文件中包含了 extern "C"时会出现编译语法错误。

(2)在 C 中引用 C++语言中的函数和变量时,C++的头文件需添加 extern "C",可是在 C 语言中不
能直接引用声明了 extern "C"的该头文件,应该仅将 C 文件中将 C++中定义的 extern "C"函数声明为
extern 类型。

 

 

7.readwrite,readonly,assign,retain,copy,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,非原子性访问,不加同步,多线程并发访问会提升性能。注意,若是不加此属性,则默认是两个访问方法

 

   都为原子型事务访问。锁被加到所属对象实例级(我是这么理解的...)。

 

33.线程的常见方法有哪些,你是如何处理多线程的,多线程同步问题你了解么?
线程建立的几种方式,线程的加锁,休眠,唤醒,解锁,退出,

多线程要考虑同步问题,解决同步问题的方式就是对某一资源加锁,当一个线程操做本资源时,其余线程不能操做 。

 
系统自带线程池(NSOpertionQueue)的做用:

凡是须要启动多个线程的地方均可以使用NSOpertionQueue,加入到NSOpertionQueue中的对象都须要继承NSOpertion。 NSOpertionQueue会在系统内部启动一个独立线程去执行这个被加入对象的main方法。

经常使用的地方是用nsoprationqueue 下载图片,文件。若是是本身建立一个线程池,无非就是启动多个线程的时候,

把这些线程对象放到一个大数组中,若是须要启动线程的时候,先从数组中找空闲线程来使用。

本身管理线程池最大的难题是很差处理当启动多个线程后,用户在多个界面的跳转的时候,对线程方法的回调管理。

而NSOpertionQueue能够很好的处理他。

 

34.init和initwithobject区别(语法)?

   init建立的对象不带自动释放

 

35.你链接服务器用的是什么方法,若是请求过程当中,网络出了问题这么办?
NSUrlConnection 链接后,有一系列委托方法来接受来自服务器的响应和数据,

其中接受相应的方法回获得服务器要传回的数据有多大,接受数据的方法会反复调用来不断接受服务器数据,

若是网络出了问题了,会调用一个方法让你来作相关处理。


36.你使用过json解析方式么,他们的底层是如何处理的你了解么?


json解析的用法,用框架的用法简单介绍:

底层原理遍历字符串中的字符,最终根据格式规定的特殊字符,好比{}号,[]号, : 号 等进行区分,

 {}号是一个字典的开始,[]号是一个数组的开始, : 号是字典的键和值的分水岭,最终乃是将json数据转化为字典,

字典中值多是字典,数组,或字符串而已。

 

37.xml解析的原理是什么,你还用过其余解析方式么?

NSXMLParser, 其余解析方式有自定义二进制解析,就是按字节去解析,电话会谈就是如此,

还能够是字符串之间用特殊符号链接的数据,将此数据用特殊符号能够分割成所用数据。

 

38.协议是什么,有什么做用.?


协议很像java中的接口,某个类实现协议后,就必须实现协议中规定的@require的方法,好比一个类A, 一个类B都实现某“协议”后,

这个类A的对象和B的对象均可以赋值给这个协议的类型变量,好比  id<协议> 变量名 = A类或B类的对象,

因而这个变量就完成了可以指向多个不一样的类的对象并调用对象中的实现协议的方法。

39.类别有什么做用?
类别的使用 。 类别有三大做用,

1. 可使原本须要在.h中声明的方法放到.m文件中声明,达到了可使方法不对外公开。

2. 能够方便的扩展类,甚至系统类均可以轻易扩展,维护了代码本来的结构不受影响。

3. 类别能够写到不一样的.h或.m文件中,能够分散代码到跟类别的扩展功能想关联的地方,方便查看。

40.分线程回调主线程方法是什么,有什么做用?
[self    performSelectorOnMainThread:@selector(buttonGo2) withObject:nil waitUntilDone:YES];
[self performSelector:@selector(buttonGo2) onThread:[NSThread mainThread] withObject:nil waitUntilDone:YES];
须要即时刷新ui控件的时候,常用。


41.iphone阅读器,若是要读取一个文本文件,请问你是如何处理编码问题的?另外像pdf格式的文件,你如何读取。?


iphone手机阅读器中对于PDF格式的阅读,能够直接用UIWebView控件显示,也能够从网上下到不少直接读取pdf格式的代码

直接从pdf中获得数据。

复杂表格动画
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation; -(void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;

42.你在开发大型项目的时候,如何进行内存泄露检测的?
  能够经过xcode的自带工具run---start with performance tool里有instruments下有个leaks工具,

  启动此工具后,运行项目,工具里能够显示内存泄露的状况,双击可找到源码位置,能够帮助进行内存泄露的处理。

 

43.你作iphone开发时候,有哪些传值方式,view和view之间是如何传值的?

     压栈。

 

44.让一个物体从界面中的一点运动到另一点,有哪些方法?
四种方式:1. beginAnimation

              2. 线程

              3. NSTimer

              4. 图层动画(路径)


45.你了解哪些加密方式?
   Base64, MD5, 循环右移位等.

 

46.地图定位

CLLocationManager位置管理器  使用Core Location框架来肯定iphone的位置(GPS,蜂窝基站三角网,wps三种方式)    

MKMapView提供了一套可植入的地图接口,可让咱们在应用中展现地图,并对其进行相关的操做。通常来讲,咱们能够指定一个展现区域,放一些标记在上面,还能够加盖一些层在上面。

MKMapView依赖Google map里面相关服务(如Google Earth API等),因此地图的左下角会有Google字样。

 

47.打开url

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://8004664411"]];mailto://   sms://

 

48. http网络通讯

ASIHTTPRequest 是一个直接在CFNetwork上作的开源项目:提供直接提交(HTTP POST)文件的API,异步请求与队列,自动管理上传与下载队列管理机,ASIFormDataRequest用于适合上传文件,图片数据。

 

49. 图片浏览

UIImagePickerController能够从相册,相机,胶卷里得到图片。

 

50. 对像序列化

NSCoding    encodeWithCoder   initWithCoder

NSKeyedUnarchiver   NSKeyedArchiver

 

51. 各类picker

UIDatePicker   UIPickerView

 

52. 电影播放

     MPMoviePlayerController

     音乐播放

     MPMusicPlayerController

 

53.线程 ?

      a. 线程的建立和使用规则?

         答:NSThread

                 三种方法

                - (id)init; // designated initializer

                - (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;

                + (void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument

                 - (void)start;

       b. 主分线程

          答:启动分线程,上面已提到!加到主线程方法performSelector!

          //加到主线程addData()是主线程的方法!只有加到主线程后,才能调用主线程的方法

         [target performSelector:@selector(addData:) onThread:[NSThread mainThread] withObject:item waitUntilDone:YES];

           //[target addData:item];//没有加到主线程后,调用主线程的方法!必定会崩!

 

      c.线程锁

         答:NSCondition

                 方法:

                 [thread lock];//加锁

                 sleep(n);//线程休眠

                 [thread singnal];//至关于通知,线程启动

                 [thread unlock];//解锁

                 [thread exit];//线程退出

 

54.各类 排序算法?

     希尔排序、快速排序、冒泡排序、

 

55.通讯底层原理

    答:OSI七层模型

    7 应用层:    ftp,smtp,http,telnet,tftp(经过各类协议,最终仍是包装成TCP数据包,发送到网络中!)

    6 表现层:

    5 会话层:

    4 传输层:    tcp udp

    3 网络层:    ip,ICMP,IGRP,EIGRP,OSPF,ARP

    2 数据链路层: STP,VT

    1 物理层:

 

56. 为何不少内置类如UITableViewController的delegate属性都是assign而不是retain的?

答:

      会引发循环引用

      全部的引用计数系统,都存在循环应用的问题。例以下面的引用关系:

          * 对象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两端产生没必要要的循环引用。

若是一个UITableViewController 对象a经过retain获取了UITableView对象b的全部权,这个UITableView对象b的delegate又是a,

若是这个delegate是retain方式的,那基本上就没有机会释放这两个对象了。本身在设计使用delegate模式时,也要注意这点。

 

57. 如下每行代码执行后,person对象的retain count分别是多少?

      Person *person = [[Person alloc] init]; count 1

      [person retain]; retain  count 2

      [person release];retain count 1

      [person release];retain count = 0

 

58.在一个对象的方法里面:

      self.name = “object”;

      和

      name =”object”

      有什么不一样吗?  

答:self.name = "object"会调用对象的setName()方法,会使object引用计数加1,name = "object"会直接把object赋值给当前对象的name 属性,引用计数不增长。


59.readwrite,readonly,assign,retain,copy,nonatomic属性的做用?

 

@property是一个属性访问声明,扩号内支持如下几个属性:
1,getter=getterName,setter=setterName,设置setter与getter的方法名
2,readwrite,readonly,设置可供访问级别


3,assign,setter方法直接赋值,不进行任何retain操做,为了解决原类型与环循引用问题
4,retain,setter方法对参数进行release旧值再retain新值,全部实现都是这个顺序(CC上有相关资料)


5,copy,setter方法进行Copy操做,与retain处理流程同样,先旧值release,再Copy出新的对象,retainCount为1。这是为了减小对上下文的依赖而引入的机制。


6,nonatomic,非原子性访问,不加同步,多线程并发访问会提升性能。注意,若是不加此属性,则默认是两个访问方法都为原子型事务访问。锁被加到所属对象实例级(我是这么理解的…)。

7,@synthesize xxx; 来实现实际代码

60.1.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].

相关文章
相关标签/搜索