iOS-面试题-OC基础篇 (2) - (83)

前言:面试笔试都是必考语法知识点。请认真复习和深入研究OC。

目录:
iOS-面试题-OC基础篇 (1) - (84)
iOS-面试题-OC基础篇 (2) - (83)

1. UDID&UUID

UDID
是 Unique Device Identifier 的缩写,中文意思是设备唯一标识.

在很多需要限制一台设备一个账号的应用中经常会用到,在 Symbian 时代,我们是使用 IMEI 作为设备的唯一标识的,可惜的是 Apple 官方不允许开发者获得设备的 IMEI.

[UIDevice currentDevice] uniqueIdentifier]

但是我们需要注意的一点是,对于已越狱了的设备,UDID 并不是唯一的.使用 Cydia 插件 UDIDFaker,可以为每一个应用分配不同的 UDID. 所以 UDID 作为标识唯一设备的用途已经不大 了.

UUID
是 Universally Unique Identifier 的缩写,中文意思是通用唯一识别码.

由网上资料显示,UUID 是一个软件建构的标准,也是被开源软件基金会(Open Software Foundation,OSF)的组织在分布式计算环境(Distributed Computing Environment,DCE)领域的 一部份.UUID 的目的,是让分布式系统中的所有元素,都能有唯一的辨识资讯,而不需要透过中央 控制端来做辨识资 讯的指定.

备注:UDID 并不是一定不会变,如:重新开关机、手机越狱都会变。决绝办法是将 UDID 保存在钥匙串中,用时去钥匙串中取。UUID 倒是永远不变的,使用 xcode 可以获取,但是没办 反通过代码获取。

[参考]:iOS-通过UUID来获取iOS设备唯一标识

2. CPU&GPU

CPU:中央处理器(英文 Central Processing Unit)是一台计算机的运算核心和控制核心。 CPU、内部存储器和输入/输出设备是电子计算机三大核心部件。其功能主要是解释计算机指令 以及处理计算机软件中的数据。

GPU:英文全称 Graphic Processing Unit,中文翻译为“图形处理器”。一个专门的图形 核心处理器。GPU 是显示卡的“大脑”,决定了该显卡的档次和大部分性能,同时也是 2D 显示 卡和 3D 显示卡的区别依据。2D 显示芯片在处理 3D 图像和特效时主要依赖 CPU 的处理能力,称 为“软加速”。3D 显示芯片是将三维图像和特效处理功能集中在显示芯 片内,也即所谓的“硬 件加速”功能。

3.点(pt)&像素(px)

像素(pixels) 是数码显示上最小的计算单位。在同一个屏幕尺寸,更高的 PPI(每英寸 的像素数目),就能显示更多的像素,同时渲染的内容也会更清晰。

点(points) 是一个与分辨率无关的计算单位。根据屏幕的像素密度,一个点可以包含多 个像素(例如,在标准 Retina 显示屏上 1 pt 里有 2 x 2 个像素)。

当你为多种显示设备设计时,你应该以“点”为单位作参考,但设计还是以像素为单位设计的。 这意味着仍然需要以 3 种不同的分辨率导出你的素材,不管你以哪种分辨率设计你的应用。

4. 属性与成员变量:

成员变量是不与外界接触的变量,应用于类的内部,如果你说那用@Public 外部不就是可以访 问了么。简单的说 public 只能适当使用,不要泛滥,否则就像你把钥匙插在你自己家门上了。 谁来都可以开门。毫无安全性。

由于成员变量的私有性,为了解决外部访问的问题就有了属性变量。属性变量个人认为最大的 好处就是让其他对象访问这个变量。而且你可以设置只读、可写等等属性,同时设置的方法我 们也可以自己定义。记住一点,属性变量主要是用于与其他对象相互交互的变量

如果对于上面所说还是含糊不清那就记住这几点吧!

 1.只有类内使用,属性为 private,那么就定义成员变量。
 2.如果你发现你需要的这个属性需要是 public 的,那么毫不犹豫就用属性在.h 中定义。
 3.当你自己内部需要 setter 实现一些功能的时候,用属性在.m 中定义。
 4.当你自己内部需要 getter 实现一些功能的时候,用属性在.m 中定义。

5. 全局变量和静态变量的区别:

1> 修饰符

 全局变量在声明源文件之外使用,需要extern引用一下; 静态变量使用static来修饰

2> 存储地址

 两者都是存储在静态存储区,非堆栈上,它们与局部变量的存储分开

3> 生命周期

 两者都是在程序编译或加载时由系统自动分配的,程序结束时消亡

4> 外部可访问性

  全局变量在整个程序的任何地方均可访问,而静态变量相当于面向对象中的私有变量,他的 可访问性只限定于声明它的那个源文件,即作用于仅局限于本文件中

6. 分类 拓展 协议中哪些可以声明属性?

都可以,但分类和协议创建的属性只相当于方法,但是内部没有对成员变量的操作(无法创 建成员变量),拓展可以(私有成员变量)

代理中声明属性,没有实际创建成员变量,相当于声明了属性名对应的访问方法,遵守协议 的类需要实现对应的访问器方法,否则运行报错

分类中声明属性,警告􏰀示需要手动实现访问器方法(Swift中叫计算型属性),而分类中不 能创建成员变量,可以在手写访问器方法中使用runtime的 objc_setAssociatedObject方法关 联对象间接创建属性(静态库添加属性)

拓展里可以声明属性,直接可以使用

7. 继承和类别的区别
答:

(1)使用继承:

 继承可以增加,修改或者删除方法,并且可以增加属性。
 添加新方法和父类方法一致,但父类方法仍需要使用

(2)类别:

 1> 针对系统提供的一些类,系统本身不提倡继承,因为这些类的内部实现对继承有所限制
 2> 类别可以将自己构建的类中的方法进行分组,对于大型的类,􏰀高可维护性

(3)分类的作用

 1> 将类的实现分散到多个不同文件或多个不同框架中。
 2> 创建对私有方法的前向引用。
 3> 向对象添加非正式协议。

 (非正式协议:即NSObject的分类,声明方法可以不实现,OC2.0以前protocal没有@optional,主要使用分类添加可选协议方法

  oc中声明方法不实现,不调用则只警告不报错

 正式协议的优点:可继承,泛型约束

 如kvo的observeValueForKeyPath属于nsobject的分类,且不需要调父类,说明可选实现该 方法,没警告可能是编译器规则过滤)

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

(5)分类的局限性

 无法向类中添加新的实例变量,类别没有位置容纳实例变量。
 无法添加实例变量的局限可以使用字典对象解决。

8. category&extension

类别主要有三个作用

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

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

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

他们的主要区别是:

 1、形式上来看,extension 是匿名的 category。
 2、extension 里声明的方法需要在 main implementation 中实现,category 不强制要求。
 3、extension 可以添加属性(变量),category 不可以。

Category 和 Extension 都是用来给已定义的类增加新的内容的。

  4、Category 和原有类的耦合更低一些,声明和实现都可以写在单独的文件里。但是只能 为已定义类增加 Method,而不能加入实例变量。
  5、extensions可以认为是一个私有的Category。

Extension 耦合比较高,声明可以单独写,但是实现必须写在原有类的@implementation 中。可以增加 Method 和实例变量。

Extension 给人感觉更像是在编写类时为了封装之类的特性而设计,和类是同时编写的。 而 category 则是在用到某一个 framework 中的类时临时增加的特性。

Extension 的一个特性就是可以重新声明一个实例变量,将之从 readonly 改为对内 readwrite.

使用 Extension 可以更好的封装类,在 h 文件中能看到的都是对外的接口,其余的实例变 量和对内的@property 等都可以写在 Extension,这样类的结构更加清晰。

9. 字符串常用处理

1. 字符串比较

 NSString *a = @“hello”;
 NSString *b = [NSString stringWithFormat:@hello”];

 if (a == b) NSLog(@“a==b”);
 if ([a isEqualToString: b]) NSLog(@“a isEqualToString b”);

 == 比较变量中保存的数值(地址) 速度快 内容同,可能地址不同(常量区,堆区)
 isEqualTo 比较字符串 非常耗时

2. 字符串截取
截取字符串”20 | http://www.baidu.com”中,”|”字符前面和后面的数据,分别输出它们。

 NSString * str = @"20 | http://www.baidu.com";
 NSArray *array = [str componentsSeparatedByString:@"|"]; //这是分别输出的截取后的字 符串

 for (int i = 0; i<[array count]; ++i) {
  NSLog(@"%d=%@",i,[array objectAtIndex:i]);
  }

3.格式

 NSString *str1 = [NSString stringWithFormat:@"a"b”]; //报错,a”后面加b是违法的
 NSString *str2 = [NSString stringWithFormat:@“a""b”]; //显示 ab
 NSString *str3 = [NSString stringWithFormat:@“a\"b”]; //显示 a”b 反斜杠转义

10. NSArray和NSDictionary - 遍历数组/字典的方法

数 组: 
    for 循 环 
    forin 
    enumerateObjectsUsingBlock ( 正 序 )
    enumerateObjectsWithOptions:usingBlock:(多一个遍历选项,不保证顺序)

字 典:

     1. for(NSString *object in [testDic allValues])

     2. for(id akey in [testDic allKeys]){
        [sum appendString:[testDic objectForKey:akey]]; }

     3. [testDic enumerateKeysAndObjectsUsingBlock:^(idkey,idobj,BOOL*stop) {
        [sum appendString:obj]; } ];

速度: 对于数组, 增强for最快,普通for和block速度差不多,增强最快是因为增强for语法会对容器里的元素的内存地址建立缓冲,遍历的时候直接从缓冲中取元素地址而不是通过调用方 法来获取,所以效率高.这也是使用增强for时不能在循环体中修改容器元素的原因之一(可以在 循环体中添加标记,在循环体外修改元素)

对于字典,allValues最快,allKey和block差不多,原因是allKey需要做objcetForKey的方法

11. 如何避免循环引用

两个对象相互强引用,都无法release,解决办法为一个使用strong,一个使用assign(weak)

12. CFSocket使用有哪几个步骤
答:

 1、创建 Socket 的上下文
 2、创建 Socket
 3、配置要访问的服务器信息
 4、封装服务器信息
 5、连 接服务器;

13. oc几种操作Socket的方法?

CFNetwork 、CFSocket 和 BSD Socket 。AsyncSocket

14.解析XML文件有哪几种方式?

 以 DOM 方式解析 XML 文件;
 以 SAX 方式解析 XML 文件;

15.什么是沙盒模型?哪些操作是属于私有api范畴?

  某个iphone工程进行文件操作有此工程对应的指定的位置,不能逾越。

  iphone沙箱模型的有四个文件夹documents,tmp,app,Library,永久数据存储一般放 documents文件夹,
  得到模拟器的路径的可使用NSHomeDirectory()方法。

  Nsuserdefaults保存 的文件在tmp文件夹里。

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

  self.name =”object”:会调用对象的setName()方法,   
  name = “object”:会直接把object赋值给当前对象的name属性。

17. 创建控制器、视图的方式

创建控制器的方式

 (1)通过代码的方式加载UIViewController *controller = [[UIViewController alloc] init];

 (2)通过stroyboard来加载viewController
    加载storyboard中箭头指向的viewController
  UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];

 //加载箭头指向的viewController
  CZViewController *controller = [storyboard instantiateInitialViewController];
  加载storyboard中特定标示的viewController(storyboard可以有多个controller)
  UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
  CZViewController*controller= [storyboardinstantiateViewControllerWithIdentifier:@"two"];



 (3)传统方法

 1.创建Xib,并指定xib的files owner为自定义控制器类(为了能连线关联管理IB的内容)

 2. xib中要有内容,且xib中􏰁述的控制器类的view属性要与xib的view控件完成关联
   (关联方 法两种,一种是control+files owner拖线到xib中搭建的指定view控件,另一种是指定xib中的 view拖线到@interface)

 3.从xib加载viewController
 CZViewController *controller = [[CZViewController alloc] initWithNibName:@"CZOneView" bundle:nil];

 4.bundle中取出xib内容
 CZViewController *vc = [[NSBundle mainBundle] loadNibNamed:@"Two" owner:nil options:nil].lastObject;

创建视图的方式

 1.用系统的loadView方法创建控制器的视图
 2.如果指定加载某个storyboard文件做控制器的视图,就会加载storyboard里面的描述去创建 view
 3.如果指定读取某个xib文件做控制器的视图,就根据指定的xib文件去加载创建
 4.如果有xib文件名和控制器的类名前缀(也就是去掉controller)的名字一样的 xib文件 就 会用这个xib文件来创建控件器的视图 
   例:控件器的名为 MJViewController xib文件名为 MJView.xib
   如果xib文件名后有一个字不一样就不会去根据它去创建如:MJView8.xib
 5.找和控制器同名的xib文件去创建
 6.如果以上都没有就创建一个空的控制器的视图;

18. UIWindow
是一种特殊的UIView,通常在一个程序中只会有一个UIWindow,但可以手 动创建多个UIWindow, 同时加到程序里面。

 UIWindow在程序中主要起到三个作用:
 1、作为容器,包含app所要显示的所有视图
 2、传递触摸消息到程序中view和其他对象
 3、与UIViewController协同工作,方便完成设备方向旋转的支持

19. 简述内存分区情况

 1).代码区:存放函数二进制代码
 2).数据区:系统运行时申请内存并初始化,系统退出时由系统释放。存放全局变量、静态变量、 常量
 3).堆区:通过malloc等函数或new等操作符动态申请得到,需程序员手动申请和释放
 4).栈区:函数模块内申请,函数结束时由系统自动释放。存放局部变量、函数参数

20.队列和栈有什么区别
队列和栈是两种不同的数据容器。从”数据结构”的角度看,它们都是线性结构,即数据 元素之间的关系相同。

 队列是一种先进先出的数据结构,它在两端进行操作,一端进行入队列操作,一端进行出列队 操作

 栈是一种先进后出的数据结构,它只能在栈顶进行操作,入栈和出栈都在栈顶操作。

21 .iOS的系统架构

  iOS的系统架构分为四个层次:
 ( 核心操作系统层 theCore OS layer )
 ( 核心服务层theCore Services layer )
 ( 媒体层 theMedia layer )
 ( Cocoa 界面服务层 the Cocoa Touch layer )

22 .控件主要响应3种事件

 1). 基于触摸的事件 ;
 2). 基于值的事件 ;
 3). 基于编辑的事件。

23 .xib文件的构成分为哪3个图标?都具有什么功能。

 File’s Owner 是所有 nib 文件中的每个图标,它表示从磁盘加载 nib 文件的对象;
 First Responder 就是用户当前正在与之交互的对象;
 View 显示用户界面;完成用户交互;是 UIView 类或其子类。

24 .简述视图控件器的生命周期。

loadView在controller的view为nil时调用。尽管不直接调用该方法,如手动创建自己的 视图,那么应该覆盖这个方法并将它们赋值给试图控制器的 view 属性。在C的View为nil时调 用,在编程实现View时调用。

 viewDidLoad 只有在视图控制器将其视图载入到内存之后才调用该方法,
 这是执行任何其他初始化操作的入口。在View从nib初始化的时候调用。

 viewVillAppear 当试图将要添加到窗口中并且还不可见的时候或者上层视图移出图层后本视 图变成顶级视图时调用该方法,
 用于执行诸如改变视图方向等的操作。实现该方法时确保调用 [super viewWillAppear:]

 viewDidAppear 当视图添加到窗口中以后或者上层视图移出图层后本视图变成顶级视图时调用,
 用于放置那些需要在视图显示后执行的代码。确保调用 [super viewDidAppear:] 。

 viewWillDisappear-UIViewController对象的视图即将消失、被覆盖或是隐藏时调用

 viewDidDisappear-UIViewController对象的视图已经消失、被覆盖或是隐藏时调用;

 viewVillUnload-当内存过低时,需要释放一些不需要使用的视图时,即将释放时调用;

 viewDidUnload 当试图控制器从内存释放自己的方法的时候调用,当内存过低,
 释放一些不需 要的视图。在这里实现将retain的view release,如果是retain
 的IBOutlet view 属性则不要 在这里release,IBOutlet会负责release 。

25 .应用的生命周期 各个程序运行状态时代理的回调

 -(BOOL)application:(UIApplication*)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
 告诉代理进程启动但还 没进入状态保存 

 -(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
 告诉代理启动基本完成程序准备开始运行

 - (void)applicationWillResignActive:(UIApplication *)application (挂起)
 1-当有电话进来或者锁屏,这时你的应用程会挂起,在这时,UIApplicationDelegate委托会收到通知,调用 applicationWillResignActive 方法,你可以重写这个方法,做挂起前的工作,比如关闭网络,保存数据。
 2- 当你的程序被挂起后他不会在后台运行。

 - (void)applicationDidBecomeActive:(UIApplication *)application(复原)
 当程序复原时,另一个名为 applicationDidBecomeActive 委托方法会被调用,在此你可以通过之前挂起前保存的数据来恢复你的应用程序。
 注意:应用程序在启动时,在调用了 applicationDidFinishLaunching 方法之后也会调用 applicationDidBecomeActive 方法,所以你要确保你的代码能够分清复原与启动,避免出现逻辑上的bug。

 - (void)applicationDidEnterBackground:(UIApplication *)application
当程被序被推送到后台的时候调用。所以要设置后台继续运行,则在这个函数里面设置即可

 - (void)applicationWillEnterForeground:(UIApplication *)application
 当程序从后台将要重新回到前台时候调用,这个刚好跟上面的那个方法相反。

  - (void)applicationWillTerminate:(UIApplication *)application
 当程序将要退出是被 调用,通常是用来保存数据和一些退出前的清理工作。

参考:IOS开发 applicationDidBecomeActive 应用程序挂起、复原与终止

26.简要说明一下 APP 的启动过程,main 文件说起,main 函数中有什
么函数?作用是什么?

打开程序——->执行 main 函数———>UIAPPlicationMain 函数——->初始化 UIAPPlicationMain 函数(设置代理,开启事件循环)———>监听系统事件—->程序结束

先执行 main 函数,main 内部会调用 UIApplicationMain 函数

UIApplicationMain 函数作用:
(1)根据传入的第三个参数创建 UIApplication 对象或它的子类对象。如果该参数为 nil,直接 使用该 UIApplication 来创建。(该参数只能传人 UIApplication 或者是它的子类)

(2)根据传入的第四个参数创建 AppDelegate 对象,并将该对象赋值给第 1 步创建的 UIApplication 对象的 delegate 属性。

(3)开启一个事件循环,循环监控应用程序发生的事件。每监听到对应的系统事件时,就会通知 AppDelegate。

 main 函数作用:
 (1)创建 UIApplication 对象
 (2)创建应用程序代理
 (3)开启时间循环,包括应用程序的循环运行,并开始处理用户事件。

参考:iOS-关于应用/视图的生命周期及程序启动原理小结

27.动画有基本类型有哪几种;表视图有哪几种基本样式。

 答:动画有两种基本类型:隐式动画和显式动画。

28.Cocoa Touch提供了哪几种Core Animation过渡类型?

 答: Cocoa Touch 提供了 4 种 Core Animation 过渡类型,分别为:交叉淡化、推挤、显示 和覆盖。

29.Quatrz 2D的绘图功能的三个核心概念是什么并简述其作用。

 答:上下文:主要用于􏰁述图形写入哪里;
 路径:是在图层上绘制的内容;
 状态:用于保存配置变换的值、填充和轮廓, alpha 值等。

30.Phone OS主要提供了几种播放音频的方法?

 答: SystemSound Services、AVAudioPlayer、Audio Queue Services、OpenAL

31.使用AVAudioPlayer类调用哪个框架、使用步骤?

 答: AVFoundation.framework
 步骤:配置 AVAudioPlayer 对象;
 实现 AVAudioPlayer 类的委托方法;
 控制 AVAudioPlayer 类的对象;
 监控音量水平;
 回放进度和拖拽播放。

32.有哪几种手势通知方法、写清楚方法名?

-(void)touchesBegan:(NSSet*)touchedwithEvent:(UIEvent*)event;
-(void)touchesMoved:(NSSet*)touched withEvent:(UIEvent*)event;
-(void)touchesEnded:(NSSet*)touchedwithEvent:(UIEvent*)event;
-(void)touchesCanceled:(NSSet*)touchedwithEvent:(UIEvent*)event;

33.ViewController的didReceiveMemoryWarning怎么被调用

 答:[super didReceiveMemoryWarning];

34.用预处理指令#define声明一个常数,用以表明1年中有多少秒(忽
略闰年问题)

 #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
 我在这想看到几件事情:
 #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等)

 懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不 是计算出实际的值,是更清晰而没有代价的。

 意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常 数是的长整型数。

 如果你在你的表达式中用到UL(表示无符号长整型),那么你有了一个好的起点。记住,第一印 象很重要。

35.写一个”标准"宏MIN ,这个宏输入两个参数并返回较小的一个

 #define MIN(A,B) ((A) <= (B) ? (A) : (B))
 
 这个测试是为下面的目的而设的:
 标识#define在宏中应用的基本知识。这是很重要的,因为直到嵌入(inline)操作符变为标准C 的一部分,宏是方便产生嵌入代码的唯一方法,

 对于嵌入式系统来说,为了能达到要求的性能,嵌入代码经常是必须的方法。
 三重条件操作符的知识。这个操作符存在C语言中的原因是它使得编译器能产生比 if-then-else 更优化的代码,了解这个用法是很重要的。

懂得在宏中小心地把参数用括号括起来

我也用这个问题开始讨论宏的副作用,例如:当你写下面的代码时会发生什么事?

 least = MIN(*p++, b);
 least = MIN(*p++, b);
 结果是:
 ((*p++) <= (b) ? (*p++) : (*p++))
 ((*p++) <= (b) ? (*p++) : (*p++))
 这个表达式会产生副作用,指针p会作三次++自增操作。

36.关键字const有什么含意?修饰类呢?static的作用,用于类呢?还
有externc的作用,const 意味着"只读",下面的声明都是什么意思?

 const int a;    a是一个常整型数
 int const a;    a是一个常整型数
 const int *a;    一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)。

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

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

如果你曾花很多时间清理其它人留下的垃圾,你就会很快学会感谢这点多余的信息。(当然,懂 得用const的程序员很少会留下的垃圾让别人来清理的) 通过给优化器一些附加的信息,使用 关键字const也许能产生更紧凑的代码。合理地使用关键字const可以使编译器很自然地保护那 些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug的出现。

 1).欲阻止一个变量被改变,可以使用 const 关键字。在定义该 const 变量时,通常需要对它 进行初始化,因为以后就没有机会再去改变它了;

 2).对指针来说,可以指定指针本身为 const,也可以指定指针所指的数据为 const,或二者同 时指定为 const;

 3).在一个函数声明中,const 可以修饰形参,表明它是一个输入参数,在函数内部不能改变其 值;

 4).对于类的成员函数,若指定其为 const 类型,则表明其是一个常函数,不能修改类的成员变量;

 5).对于类的成员函数,有时候必须指定其返回值为 const 类型,以使得其返回值不为“左值”。

37.关键字volatile有什么含意?并给出三个不同的例子。
答:一个定义为 volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去 假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这 个变量的值,而不是使用保存在寄存器里的备份。

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

38.一个参数既可以是const还可以是volatile吗?一个指针可以是
volatile吗?

 答:1).是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它 是const因为程序不应该试图去修改它。

    2).是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。

39.static 关键字的作用

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

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

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

41.进程之间通信的途径

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

42.进程死锁的原因

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

43.死锁的4个必要条件

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

44.死锁的处理

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

45.cocoa touch框架
答:iPhone OS 应用程序的基础 Cocoa Touch 框架重用了许多 Mac 系统的成熟模式,但是它 更多地专注于触摸的接口和优化。

UIKit 为您􏰀供了在 iPhone OS 上实现图形,事件驱动程序的基本工具,其建立在和 Mac OS X 中一样的 Foundation 框架上,包括文件处理,网络,字符串操作等。

Cocoa Touch 具有和 iPhone 用户接口一致的特殊设计。有了 UIKit,您可以使用 iPhone OS 上 的独特的图形接口控件,按钮,以及全屏视图的功能,您还可以使用加速仪和多点触摸手势来 控制您的应用。

各色俱全的框架 除了UIKit 外,Cocoa Touch 包含了创建世界一流 iPhone 应用程序需要的所 有框架,从三维图形,到专业音效,甚至􏰀供设备访问 API 以控制摄像头,或通过 GPS 获知 当前位置。

Cocoa Touch 既包含只需要几行代码就可以完成全部任务的强大的 Objective-C 框架,也在需 要时􏰀供基础的 C 语言 API 来直接访问系统。这些框架包括:

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

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

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

功能列表:框架分类

 下面是 Cocoa Touch 中一小部分可用的框架:
  音频和视频:Core Audio ,OpenAL ,Media Library ,AV Foundation
  数据管理 :Core Data ,SQLite
  图形和动画 :Core Animation ,OpenGL ES ,Quartz 2D
  网络:Bonjour ,WebKit ,BSD Sockets
  用户应用:Address Book ,Core Location ,Map Kit ,Store Kit

46.自动释放池是什么,如何工作
答:当您向一个对象发送一个autorelease消息时,Cocoa就会将该对象的一个引用放入到最新 的自动释放.它仍然是个正当的对象,因此自动释放池定义的作用域内的其它对象可以向它发送 消息。当程序执行到作用域结束的位置时,自动释放池就会被释放,池中的所有对象也就被释 放。

47.sprintf,strcpy,memcpy使用上有什么要注意的地方。

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

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

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

48.你了解svn,cvs等版本控制工具么?
答: 版本控制 svn,cvs 是两种版控制的器,需要配套相关的svn,cvs服务器。scm是xcode里配 置版本控制的地方。版本控制的原理就是a和b同时开发一个项目,a写完当天的代码之后把代码 􏰀交给服务器,b要做的时候先从服务器得到最新版本,就可以接着做。 如果a和b都要􏰀交给 服务器,并且同时修改了同一个方法,就会产生代码冲突,如果a先􏰀交,那么b􏰀交时,服务器可以􏰀示冲突的代码,b可以清晰的看到,并做出相应的修改或融合后再􏰀交到服务器。

49.什么是push
答: 客户端程序留下后门端口,客户端总是监听针对这个后门的请求,于是 服务器可以主动 像这个端口推送消息。

50.静态链接库
答:此为.a文件,相当于java里的jar包,把一些类编译到一个包中,在不同的工程中如果导入 此文件就可以使用里面的类,具体使用依然是#import “ xx.h”。

51.三大特性

1.封装_点语法

 (1)本质
 //以下代码有什么问题
 - (void)setName:(NSString *)name {
     self.name = name;
 }
 - (NSString *)name { 
       return self.name;
   }
 (2)点语法的本质是调用类的getter方法和setter方法,如果类中没有getter方法和setter方法 就不能使用点语法。

2.继承

 (1)如何实现多重继承消息转发
 forwardingTargetForSelector methodSignatureForSelector delegate和protocol 类别

Objective-C 的“多继承”

3.多态

1> 什么是多态
多态:不同对象以自己的方式响应相同的消息的能力叫做多态。子类指针可以赋值给父类。 由于每个类都属于该类的名字空间,这使得多态称为可能。类定义中的名字和类定义外的名字并不会冲突。类的实例变量和类方法有如下特点:

• 和C语言中结构体中的数据成员一样,类的实例变量也位于该类独有的名字空间。

• 类方法也同样位于该类独有的名字空间。与C语言中的方法名不同,类的方法名并不是一个全 局符号。一个类中的方法名不会和其他类中同样的方法名冲突。两个完全不同的类可以 实现同一个方法。

方法名是对象接口的一部分。对象收到的消息的名字就是调用的方法的名字。因为不同的对象 可以有同名的方法,所以对象必须能理解消息的含义。同样的消息发给不同的对象,导致的操 作并不相同。

多态的主要好处就是简化了编程接口。它容许在类和类之间重用一些习惯性的命名,而不用 为每一个新加的函数命名一个新名字。这样,编程接口就是一些抽象的行为的集合,从而和实 现接口的类区分开来。

Objective-C支持方法名的多态,但不支持参数和操作符的多态。

2> OC中如何实现多态
在Objective-C中是通过一个叫做selector的选取器实现的。在Objective-C中,selector有两个意思, 当用在给对象的源码消息时,用来指方法的名字。它也指那个在源码编译后代替 方法名的唯一的标识符。 编译后的选择器的类型是SEL有同样名字的方法、也有同样的选择器。 你可以使用选择器来调用一个对象的方法。

选取器有以下特点:

 * 所有同名的方法拥有同样的选取器
 * 所有的选取器都是不一样的

(1) SEL和@selector
选择器的类型是 SEL。@selector指示符用来引用选择器,返回类型是SEL。

 例如:SEL responseSEL; responseSEL = @selector(loadDataForTableView:); 可以通过字符串来得到选取器,
 例如:responseSEL = NSSelectorFromString(@"loadDataForTableView:"); 也可以通过反向转换,得到方法名,
 例如:NSString *methodName = NSStringFromSelector(responseSEL);

(2) 方法和选取器
选取器确定的是方法名,而不是方法实现。这是多态性和动态绑定的基础,它使得向不同 类对象发送相同的消息成为现实;否则,发送消息和标准C中调用方法就没有区别,也就不可能 支持多态性和动态绑定。

另外,同一个类的同名类方法和实例方法拥有相同的选取器。

(3) 方法返回值和参数类型
消息机制通过选取器找到方法的返回值类型和参数类型,因此,动态绑定(例:向id定义 的对象发送消息)需要同名方法的实现拥有相同返回值类型和相同的参数类型;否则,运行时 可能出现找不到对应方法的错误。

一个例外,虽然同名类方法和实例方法拥有相同的选取器,但是它们可以有不同的参数 类型和返回值类型。

3> 动态绑定

52. OC的优缺点。

 答:
 优点:1).Cateogies
     2).Posing 
     3).动态识别 
     4).指标计算 
     5).弹性讯息传递 
     6).不是一个过度复杂的C衍生语言 
     7).Objective-C 与 C++ 可混合编程

 缺点:
      1).不支持命名空间 
      2).不支持运算符重载 
      3).不支持多重继承 
      4).使用动态运行 时类型,所有的方法都是函数调用,所以很多编译时优化方法都用不到。(如内联函数等),性 能低劣。

       对于命名冲突可以使用长命名法或特殊前缀解决,
       如果是引入的第三方库之间的命名冲突, 可以使用link命令及flag解决冲突

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

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

答:多态。主要是将数据类型的确定由编译时,推迟到了运行时。这个问题其实浅涉及到两个 概念,运行时和多态。

简单来说,运行时机制使我们直到运行时才去决定一个对象的类别,以及调用该类别对象指定 方法。

 多态:不同对象以自己的方式响应相同的消息的能力叫做多态。

意思就是假设生物类(life)都用有一个相同的方法-eat。那人类属于生物,猪也属于生物,都 继承了life后,实现各自的eat,但是调用是我们只需调用各自的eat方法。也就是不同的对象 以自己的方式响应了相同的消息(响应了eat这个选择器)。因此也可以说,运行时机制是多态的 基础?~~~

55. 什么是谓词?

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

56. 简单介绍下NSURLConnection类及+sendSynchronousRequest:returningResponse:error:与 –
initWithRequest:delegate:两个方法的区别?

 答 :NSURLConnection 主 要 用 于 网 络 访 问 , 其 中 + sendSynchronousRequest:returningResponse:error:是同步访问数据
 当前线程会阻塞,并 等待request的返回的response。

 而– initWithRequest:delegate:使用的是异步加载,当其完 成网络访问后,
 会通过delegate回到主线程,并其委托的对象。

57.谈谈OC的内存管理方式及过程?

 答: 
     1).当你使用new,alloc和copy方法创建一个对象时,该对象的保留计数器值为1.
        当你不再 使用该对象时,你要负责向该对象发送一条release或autorelease消息.
        这样,该对象将在使用 寿命结束时被销毁.


     2).当你通过任何其他方法获得一个对象时,则假设该对象的保留计数器值为1,
        而且已经被设置 为自动释放,你不需要执行任何操作来确保该对象被清理.
        如果你打算在一段时间内拥有该对象, 则需要保留它并确保在操作完成时释放它.

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

58.OC有私有方法吗?私有变量呢?

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

 @interface Controller : NSObject {
   NSString *something;
 }

 + (void)thisIsAStaticMethod;
 – (void)thisIsAnInstanceMethod;
 @end

 @interface Controller (private)
 - (void)thisIsAPrivateMethod;
 @end

 @private可以用来修饰私有变量
 在Objective‐C中,所有实例变量默认都是私有的,所有实例方法默认都是公有的

参考:为什么说 Objective-C 没有私有方法和私有变量

59.事件传递&响应者链

事件响应链:

 包括点击事件,画面刷新事件等。在视图栈内从上至下,或者从下之上传播。可 以说点事件的分发,传递以及处理。

事件的产生和传递过程:

 1.当触摸事件发生时,压力转为电信号,iOS系统将产生UIEvent对象,记录事件产生的时间
   和类型,然后系统将事件加入到一个由UIApplication管理的事件队列中。

 2.UIApplication 会从事件队列中取出最前面的事件,并将事件分发下去以便处理,通常
   会先发送事件给应用程序的主窗口(keyWindow)

 3.主窗口会在视图层次结构中找到一个最合适的视图来处理触摸事件

 4.找到合适的视图控件后,就会调用视图控件的 touches 方法来作事件的具体处理: touchesBegin... touchesMoved...touchesEnded 等

 5.这些 touches 方法默认的做法是将事件顺着响应者链条向上传递,将事件叫个上一个相 应者进行处理
   一般事件的传递是从父控件传递到子控件的

如果父控件接受不到触摸事件,那么子控件就不可能接收到触摸事件 UIView 不能接收触摸事 件的三种情况:

 1.不接受用户交互:userInteractionEnabled = NO;
 2.隐藏:hidden = YES;
 3.透明:alpha = 0.0~0.01

 用户的触摸事件首先会由系统截获,进行包装处理等。
 然后递归遍历所有的 view,进行碰触测试(hitTest),直到找到可以处理事件的 view。

  - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
 // recursively calls -pointInside:withEvent:. point is in the receiver's coordinate system
  - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;
 // default returns YES if point is in bounds

 大致的过程 application –> window –> root view –>......–>lowest view

响应者链

 响应者链条:其实就是很多响应者对象(继承自 UIResponder 的对象)一起组合起来的链条称之为响应者链条

一般默认做法是控件将事件顺着响应者链条向上传递,将事件交给上一个响应者进行处理。 那么如何判断当前响应者的上一个响应者是谁呢?有以下两个规则:

 1.判断当前是否是控制器的 View,如果是控制器的 View,上一个响应者就是控制器
 2.如果不是控制器的 View,上一个响应者就是父控件

当有 view 能够处理触摸事件后,开始响应事件。 系统会调用 view 的以下方法:

 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
 - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

 可以多对象共同响应事件。只需要在以上方法重载中调用 super 的方法。
 大致的过程 initial view –> super view –> .....–> view controller –> window –> Application

需要特别注意的一点是,传递链中时没有 controller 的,因为 controller 本身不具有大 小的概念。但是响应链中是有 controller 的,因为 controller 继承自 UIResponder。

 UIApplication–>UIWindow–>递归找到最合适处理的控件–>控件调用 touches 方法–>判断 是 否实现 touches 方法–>没有实现默认会将事件传递给上一个响应者–>找到上一个响应者 –>找不到方法作废      

PS:利用响应者链条我们可以通过调用 touches 的 super 方法,让多个响应者同时响应该事件。

60.frame和bounds有什么不同?

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

61.方法和选择器有何不同?
答:selector是一个方法的名字,method是一个组合体,包含了名字和实现,详情可以看apple 文档。

62.什么是延迟加载?

答:懒汉模式,只在用到的时候才去初始化,也可以理解成延时加载。

我觉得最好也最简单的一个列子就是tableView中图片的加载显示了。一个延时载,避免内存过 高,一个异步加载,避免线程堵塞。

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

64.一个tableView是否可以关联两个不同的数据源?你会怎么处理?
答:首先我们从代码来看,数据源如何关联上的,其实是在数据源关联的代理方法里实现的。 因此我们并不关心如何去关联他,他怎么关联上,方法只是让我返回根据自己的需要去设置如 相关的数据源。

因此,我觉得可以设置多个数据源啊,但是有个问题是,你这是想干嘛呢?想让列表如何显示, 不同的数据源分区块显示?

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

66.在应用中可以创建多少autorelease对象,是否有限制?
答案:无

67.如果我们不创建内存池,是否有内存池􏰀供给我们?
答:界面线程维护着自己的内存池,用户自己创建的数据线程,则需要创建该线程的内存池

68.什么时候需要在程序中创建内存池?
答:用户自己创建的数据线程,则需要创建该线程的内存池

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

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

 答:简便构造方法一般由CocoaTouch框架􏰀供,如NSNumber的
 + numberWithBool: + numberWithChar: + numberWithDouble: + numberWithFloat:
 + numberWithInt: + numberWithBool: + numberWithChar: + numberWithDouble:
 + numberWithFloat: + numberWithInt:

Foundation下大部分类均有简便构造方法,我们可以通过简便构造方法,获得系统给我们创建 好的对象,并且不需要手动释放。

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

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

 UIViewAnimationOptionCurveEaseInOut 
 UIViewAnimationOptionCurveEaseIn 
 UIViewAnimationOptionCurveEaseOut 
 UIViewAnimationOptionTransitionFlipFromLeft
 UIViewAnimationOptionTransitionFlipFromRight 
 UIViewAnimationOptionTransitionCurlUp 
 UIViewAnimationOptionTransitionCurlDown 
 UIViewAnimationOptionCurveEaseInOut 
 UIViewAnimationOptionCurveEaseIn 
 UIViewAnimationOptionCurveEaseOut 
 UIViewAnimationOptionTransitionFlipFromLeft 
 UIViewAnimationOptionTransitionFlipFromRight 
 UIViewAnimationOptionTransitionCurlUp 
 UIViewAnimationOptionTransitionCurlDown

73. C和OC如何混用?

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。

74. 深拷贝与前拷贝区别?

1>深拷贝与前拷贝区别:

 浅拷贝:是指针拷贝,对一个对象进行浅拷贝,相当于对指向对象 的指>针进行复制,产生一个新的指向这个对象的指针,
 那么就是有两个指针指向同一个对象, 这个对象销毁后两个指针都应该置空。

 深拷贝:是对一个对象进行拷贝,相当于对对象进行复制, 产生一个新的对象,那么就有两个指针分别指向两个对象。
 当一个对象改变或者被销毁后拷贝 出来的新的对象不受影响。

实现深拷贝需要实现 NSCoying 协议,实现- (id)copyWithZone:(NSZone *)zone 方法。当 对一个 property 属性含有 copy 修饰符的时候,在进行赋值操作的时候实际上就是调用这个方 法。

父类实现深拷贝之后,子类只要重写 copyWithZone 方法,在方法内部调用父类的 copyWithZone 方法,之后实现自己的属性的处理

父类没有实现深拷贝,子类除了需要对自己的属性进行处理,还要对父类的属性进行处理

 浅拷贝:本质上没有产生新对象
 深拷贝:产生了新对象  

2> 什么是深拷贝浅拷贝
对于非容器类对象,不可变对象进行copy操作为浅拷贝,引用计数器加1,其他三种为深拷贝

对于容器类对象,基本和非容器类对象一致,但注意其深拷贝是对象本身是对象复制,其中元素 仍为指针复制,系统将initWithArray方法归为了元素深拷贝,但其实如果元素为不可变元素,仍 为指针复制,使用归解档可以实现真正的深拷贝,元素也是对象拷贝

 NSArray* trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:
 [NSKeyedArchiver archivedDataWithRootObject: array]];

3> 字符串什么时候使用copy,strong

 属性引用的对象由两种情况,可变和不可变字符串
 引用对象不可变情况下,copy和strong一样,copy为浅拷贝
 引用对象可变情况下,如果希望属性跟随引用对象变化,使用strong,希望不跟随变化使用copy

4> 字符串所在内存区域
@“abc” 常量区 stringwithformat 堆区

5> mutablecopy和copy @property(copy) NSMutableArray *arr;这样写有什么 问题

 mutablecopy返回可变对象,copy返回不可变对象

6> 如何让自定义类可以使用copy修饰符

 实现<NSCopying>协议,重写copyWithZone方法

75. id、NSObject、instancetype 的区别?

 Id 声明的对象具有运行时的特性,即可以指向任意类型的 Objcetive-C 的对象;
 id 是一个 objc_object 结构体指针,定义是 typedef struct objc_object *id
 id 可以理解为指向对象的指针。所有 oc 的对象 id 都可以指向,编译器不会做类型检查,
 id 调用任何存在的方法都不会在编译阶段报错,当然如果这个 id 指向的对象没有这个方法, 该崩溃还是会崩溃的。

 NSObject *指向的必须是 NSObject 的子类,调用的也只能是 NSObjec 里面的方法否则就要 做强制类型转换。
 不是所有的 OC 对象都是 NSObject 的子类,还有一些继承自 NSProxy。NSObject *可指向 的类型是 id 的子集

 instancetype 只能返回值,编译时判断真实类型,不符合发警告

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

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

77.写 一 个 setter 方 法 用 于 完 成 @property (nonatomic,retain)NSString name,写一个setter方法用于完成 @property(nonatomic,copy)NSString name

 - (void)setName:(NSString*)str { 
 if (_name != str) {
 [_name release];
 _name = [str retain]; }
 }

 - (void)setName:(NSString *)str {
 if (_name != str) {
  [_name release];
 _name = [str copy]; }
 }

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

答:Objective-C的数据类型有NSString,NSNumber,NSArray,NSMutableArray,NSData等等, 这些都是class,创建后便是对象,而C语言的基本数据类型int,只是一定字节的内存空间,用 于存放数值;NSInteger是基本数据类型Int或者Long的别名(NSInteger的定义typedef long NSInteger),NSInteger表示当前cpu下整型所占最大字节,不同CPU的long型所占字节不 同,32位int4 long4,64位int4,long8

79.OC如何对内存管理的,说说你的看法和解决方法?

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

1). (Garbage Collection)自动内存计数:这种方式和java类似,在你的程序的执行过程中。 始终有一个高人在背后准确地帮你收拾垃圾,你不用考虑它什么时候开始工作,怎样工作。你 只需要明白,我申请了一段内存空间,当我不再使用从而这段内存成为垃圾的时候,我就彻底 的把它忘记掉,反正那个高人会帮我收拾垃圾。遗憾的是,那个高人需要消耗一定的资源,在 携带设备里面,资源是紧俏商品所以iPhone不支持这个功能。所以“Garbage Collection”不 是本入门指南的范围,对“Garbage Collection”内部机制感兴趣的同学可以参考一些其他的 资料,不过说老实话“Garbage Collection”不大适合适初学者研究。

 解决: 通过alloc – initial方式创建的, 创建后引用计数+1, 此后每retain一次引用计数+1, 那么在程序中做相应次数的release就好了.

2). (Reference Counted)手动内存计数:就是说,从一段内存被申请之后,就存在一个变量用 于保存这段内存被使用的次数,我们暂时把它称为计数器,当计数器变为0的时候,那么就是释 放这段内存的时候。比如说,当在程序A里面一段内存被成功申请完成之后,那么这个计数器就 从0变成1(我们把这个过程叫做alloc),然后程序B也需要使用这个内存,那么计数器就从1变成 了2(我们把这个过程叫做retain)。紧接着程序A不再需要这段内存了,那么程序A就把这个计数 器减1(我们把这个过程叫做release);程序B也不再需要这段内存的时候,那么也把计数器减1(这个过程还是release)。当系统(也就是Foundation)发现这个计数器变 成员了0,那么就会 调用内存回收程序把这段内存回收(我们把这个过程叫做dealloc)。顺便􏰀一句,如果没有 Foundation,那么维护计数器,释放内存等等工作需要你手工来完成。

解决:一般是由类的静态方法创建的, 函数名中不会出现alloc或init字样, 如[NSString string]和[NSArray arrayWithObject:], 创建后引用计数+0, 在函数出栈后释放, 即相当于 一个栈上的局部变量. 当然也可以通过retain延长对象的生存期.

3). (NSAutoRealeasePool)内存池:可以通过创建和释放内存池控制内存申请和回收的时机.

解决:是由autorelease加入系统内存池, 内存池是可以嵌套的, 每个内存池都需要有一个创建 释放对, 就像main函数中写的一样. 使用也很简单, 比如[[[NSString alloc]initialWithFormat:@”Hey you!”] autorelease], 即将一个NSString对象加入到最内 层的系统内存池, 当我们释放这个内存池时, 其中的对象都会被释放.

80.原子(atomic)跟非原子(non-atomic)属性有什么区别??
1). atomic􏰀供多线程安全。是防止在写未完成的时候被另外一个线程读取,造成数据错误

2). non-atomic:在自己管理内存的环境中,解析的访问器保留并自动释放返回的值,如果指定 了 nonatomic ,那么访问器只是简单地返回这个值。

 原子属性采用的是"多读单写"机制的多线程策略
 "多读单写"缩小了锁范围,比互斥锁的性能好
 规定只在主线程更新UI,就是因为如果在多线程中更新,就需要给UI对象加锁,防止资源抢占写 入错误,但是这样会降低UI交互的性能,
 所以ios设计让所有UI对象都是非线程安全的(不加锁), 并规定只在主线程中更新UI,规避多线程抢占资源问题

81.看下面的程序,第一个NSLog会输出什么?这时str的retainCount是
多少?第二个和第三个呢? 为什么?

 NSMutableArray* ary = [[NSMutableArray array] retain]; 
 NSString *str =  [NSString stringWithFormat:@"test"]; 
 [str retain];
 [ary  addObject:str];
 NSLog(@”%@%d”,str,[str retainCount]);

 [str retain];
 [str release];
 [str release];
 NSLog(@”%@%d”,str,[str retainCount]); [aryremoveAllObjects];
 NSLog(@”%@%d”,str,[str retainCount]); NSMutableArray* ary = 
 [[NSMutableArray array] retain]; NSString *str = [NSString 
 stringWithFormat:@"test"]; [str retain];
 [aryaddObject:str];
 NSLog(@”%@%d”,str,[str retainCount]);
 [str retain];
 [str release];
 [str release];
 NSLog(@”%@%d”,str,[str retainCount]); [aryremoveAllObjects];
 NSLog(@”%@%d”,str,[str retainCount]); str的retainCount创建+1,
 retain+1,加入数组自动+1 3 retain+1,release-1,release-1 2 数组删除所有对象,所有数组内的对象自动-1 1

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

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

83如何对iOS设备进行性能测试?
答: Profile-> Instruments ->Time Profiler

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容