iOS其他面试题

来源:互联网 发布:李明linux百度云资源 编辑:程序博客网 时间:2024/06/01 18:08

1.         NSString的时候用copystring的区别是什么?

copy修饰的NSString,在初始化时,如果来源是NSMutableString的话,会对来源进行一次深拷贝,将来源的内存地址复制一份,这样,两个对象就一点关系就没有了,无论你怎么操作来源,都不会对自己的NSString有任何影响

 

当你给你的的NSString对象赋值时,如果来源是NSMutableString,那么这种情况就必须要用copy;如果你确定来源是不可变类型的,比如@"http://www.jianshu.com/users/691d9ed740cf/latest_articles"这种固定的字符串,那么用strong比较好

 

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

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

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

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

 

 

3.         static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?

static修饰的函数是一个内部函数,只能在本文件中调用,其他文件不能调用

static修饰的全部变量是一个内部变量,只能在本文件中使用,其他文件不能使用

static修饰的局部变量只会初始化一次,并且在程序退出时才会回收内存

 

 

4.         _block_weak修饰符的区别是什么?

__block对象在block中是可以被修改、重新赋值的。

__block对象在block中不会被block强引用一次,从而不会出现循环引用问题。

__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。

__weak只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。

__block对象可以在block中被重新赋值,__weak不可以

 

5.         如何解决TableView卡的问题?

cell复用

6.         浅拷贝和深拷贝区别是什么?

浅复制:两个实例的指针仍指向内存中的同一资源,只复制指针值而不是实际资源;深复制:不仅复制指针值,还复制指向指针所指向的资源。

 

7.         有两件功能要实现,请问是在一个线程里按顺序做效率高还是两个线程里做效率高?为什么?

 

在两个线程里做效率高,因为两件功能可同时进行

 

8.         简要说下Http通信协议原理,与Socket协议的区别有哪些?

HTTP协议是基于TCP连接的,是应用层协议,主要解决如何包装数据。Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。HTTP连接:短连接,客户端向服务器发送一次请求,服务器响应后连接断开,节省资源。服务器不能主动给客户端响应(除非采用HTTP长连接技术),iPhone主要使用类NSURLConnectionSocket连接:长连接,客户端跟服务器端直接使用Socket进行连接,没有规定连接后断开,因此客户端和服务器段保持连接通道,双方可以主动发送数据,一般多用于游戏.Socket默认连接超时时间是30秒,默认大小是8K(理解为一个数据包大小)。

 

 

9.         MVC是什么?有什么特性?你还熟悉哪些设计模式?分别应用在什么场景?

MVC设计模式考虑三种对象:模型对象、视图对象、和控制器对象。模型对象代表 特别的知识和专业技能,它们负责保有应用程序的数据和定义操作数据的逻辑。视图对象知道如何显示应用程序的模型数据,而且可能允许用户对其进行编辑。控制 器对象是应用程序的视图对象和模型对象之间的协调者。

 

10.     Objective-C堆和栈的区别?

 

栈区(stack)由编译器自动分配释放 ,存放方法(函数)的参数值, 局部变量的值等,栈是向低地址扩展的数据结构,是一块连续的内存的区域。即栈顶的地址和栈的最大容量是系统预先规定好的。堆区(heap)一般由程序员分配释放, 若程序员不释放,程序结束时由OS回收,向高地址扩展的数据结构,是不连续的内存区域,从而堆获得的空间比较灵活。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1.         解释KVOKVC的概念,并说明应用场景及注意事项?

 

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

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

 

2.         property属性有哪些,并说明下应用场景?

1> readwrite:同时生成get方法和set方法的声明和实现

2> readonly:只生成get方法的声明和实现

3> assignset方法的实现是直接赋值,用于基本数据类型

4> retainset方法的实现是release旧值,retain新值,用于OC对象类型

5> copyset方法的实现是release旧值,copy新值,用于NSStringblock等类型

6> nonatomic:非原子性,set方法的实现不加锁(比atomic性能高)

 

3.         消息传递(回调)的方式有哪些,及其适用场景?

 

delegate

    notification

    block 基本使用

    performSelector

delegatenotificationblockperformSelector 的合理使用

 

什么是函数回调?把函数实现好,等待适当的时候调用

如:实现dealloc ,系统调用该方法,实现tableView的代理方法,等待系统调用  

11delegateblock

1对多:notification

代码可复用,其他地方调用:delegatenotification

代码封装,不开放:block

耦合性高:delegateblock

耦合性低:notification

效率高:delegateblock

效率低:notification

调试难度难:notification

调试难度易:delegateblock

代码可读性、后期维护 等等 各抒己见

参考DemoTestSendMessageBetweenObject

可能考问题:

1、委托代理和通知中心的区别

2、实现函数回调有哪几种方式?

3、写一个 delegate 的声明和使用

 

 

 

4.         ARCMRC的内存管理机制有什么区别?

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

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

3> 还可以通过autorelease pool管理内存

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

 

5.         简单说明下堆内存、栈内存和VM的区别

1> 堆空间的内存是动态分配的,一般存放对象,并且需要手动释放内存

2> 栈空间的内存由系统自动分配,一般存放局部变量等,不需要手动管理内存

 

Objective-C的对象在内存中是以堆的方式分配空间的,并且堆内存是由你释放的,即release

 

栈由编译器管理自动释放的,在方法中(函数体)定义的变量通常是在栈内,因此如果你的变量要跨函数的话就需要将其定义为成员变量。

 

1.栈区(stack):由编译器自动分配释放,存放函数的参数值,局部变量等值。其操作方式类似于数据结构中的栈。

 

2.堆区(heap):一般由程序员分配释放,若程序员不释放,则可能会引起内存泄漏。注堆和数据结构中的堆栈不一样,其类是与链表。

 

操作系统iOS 中应用程序使用的计算机内存不是统一分配空间,运行代码使用的空间在三个不同的内存区域,分成三个段:“text segment “,“stack segment ”,“heap segment ”。

 

 

 

段“text segment ”是应用程序运行时应用程序代码存在的内存段。每一个指令,每一个单个函数、过程、方法和执行代码都存在这个内存段中直到应用程序退出。

 

 

 

6.         简单说明下HTTP消息体的结构

一个完整的 HTTP 请求由三个部分组成:请求行(Request Line)、消息头(Message Headers)和消息体(Entity Body),消息头与消息体之间通过空行(没有内容的行,即只有回车符和换行符)来分隔。

 

7.         列举Cocoa中常用的多线程实现,并说说多线程安全的几种解决方案,什么地方用到多线程(尽可能描述场景)?

iOS有三种多线程编程的技术,分别是:

(一)NSThread

(二)Cocoa NSOperation

(三)GCD(全称:Grand Central Dispatch

8.         请列举下常用的锁,并简单说明性能开销和优缺点?

1.NSRecursiveLock递归锁

所谓递归锁,就是在同一线程上该锁是可重入的,它对于不同线程相当于普通的互斥锁。NSRecursiveLock类定义的锁可以在同一线程多次lock,而不会造成死锁。递归锁会跟踪它被多少次lock。每次成功的lock都必须平衡调用unlock操作。只有所有的锁住和解锁操作都平衡的时候,锁才真正被释放给其他线程获得。

 

2. NSConditionLock条件锁

普通的互斥锁和递归锁都只考虑锁和解锁的问题,这样的锁无法满足多线程对访问共享资源的各种需求。因此,条件锁(NSConditionLock)的出现可以解决多线程技术中需要满足特定条件才能解开某些锁的场景。

3. NSDistributedLock分布式锁

对于多个进程或多个程序之间需要构建互斥的场景时,使用上述多线程间的锁就无法满足需求。此时,需要使用到分布式锁。分布式锁是通过文件系统实现的,它不继承自NSLock,因而也没有实现lock方法,但它提供了tryLockunlockbreakLock等方法,如果需要lock,则必须自己实现一个trylock的轮询。

 

9.         那么 runtime 如何实现 weak 变量的自动置nil

 

runtime 对注册的类, 会进行布局,对于 weak 对象会放入一个 hash 表中。  weak 指向的对象内存地址作为key,当此对象的引用计数为0的时候会 dealloc,假如 weak 指向的对象内存地址是a,那么就会以a为键, 在这个 weak 表中搜索,找到所有以a为键的 weak 对象,从而设置为 nil

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1.         什么是arcarc是为了解决什么问题诞生的?

ARC  Automatic Reference Counting 的缩写, 即自动引用计数. 这是苹果在 iOS5 中引入的内存管理机制. Objective-C  Swift 使用 ARC 追踪和管理应用的内存使用. 这一机制使得开发者无需键入 retain release , 这不仅能够降低程序崩溃和内存泄露的风险, 而且可以减少开发者的工作量, 能够大幅度提升程序的 流畅性  可预测性 . 但是 ARC 不适用于 Core Foundation 框架中, 仍然需要手动管理内存

 

2.         请解释一下keywords的区别:assign vs weak , _block vs _weak

weakassign都是引用计算不变,两个的差别在于,weak用于object type,就是指针类型,而assign用于简单的数据类型,如int BOOL 

block 不能修改局部变量,如果需要修改需要加上block.

block 会对对象强引用,引起retain-cycle,需要使用weak

__weak __typeof(&*self)weakSelf =self;

block种使用weakSelf可避免这种强引用。

(两个指针,指向同一块地址(self));

 

3.         +(void)load; +(void)initialize; 有什么用处?

load是只要类所在文件被引用就会被调用,而initialize是在类或者其子类的第一个方法被调用前调用。所以如果类没有被引用进项目,就不会有load调用;但即使类文件被引用进来,但是没有使用,那么initialize也不会被调用。

 

4.         使用drawRect有什么影响?

 

drawRect能否调用

 

用来画图,这个方法会在intiWithRect时候调用。
这个方法的影响在于有touch event的时候之后,会重新绘制,很多这样的按钮的话就会比较影响效率。以下都会被调用


1、如果在UIView初始化时没有设置rect大小,将直接导致drawRect不被自动调用。drawRect 掉用是在Controller->loadView, Controller->viewDidLoad 两方法之后掉用的.所以不用担心在 控制器中,这些ViewdrawRect就开始画了.这样可以在控制器中设置一些值给View(如果这些View draw的时候需要用到某些变量 ).


2
、该方法在调用sizeToFit后被调用,所以可以先调用sizeToFit计算出size。然后系统自动调用drawRect:方法。


3
、通过设置contentMode属性值为UIViewContentModeRedraw。那么将在每次设置或更改frame的时候自动调用drawRect:


4
、直接调用setNeedsDisplay,或者setNeedsDisplayInRect:触发drawRect:,但是有个前提条件是rect不能为0

 

5.         什么是KVO?什么是代理委托?KVO与代理委托的区别?

kvo 通过kvc 的方式修改被观察者的属性时,主动通知观察者。

kvo都是运用了设计模式中的观察者模式(监听模式), delegate是设计模式中的委托模式。

 

6.         请谈谈您对单例的认识。

单例模式常用在只需要一个实例的类的情况下,即这个类只能有一个实例对象。单例模式可以减少内存资源的浪费,而且方便外界的访问。单例模式保证一个类仅有一个实例,并且提供一个访问它的全局访问点

单例能节省内部资源,实现数据共享。

 

+(ViewController *)shareinstance{

         static viewcontroller *instance = nill;

         if(instance = nill){

         instance = [viewcontroller alloc] init];

}

return instance;

 

单例的使用场合

类中没有可以修改的成员变量(这个类没有状态),如果存在可以修改的成员变量会产生线程安全问题,除非加上synchronized 关键字,不建议使用,单例模式无法继承,所以无法扩展,无法更改它的实现。如果读取配置文件比较适合使用单例。

1.创建时需要消耗大量内存

2.需要频繁创建,调用

3.数据共享

 

//饿汉式,一开始就加载

 private static UserManager userManager=new UserManager();

 

 private UserManager(){}

 

 public static UserManager getInstance()

 {

  return userManager;

 }

 

 

 

 

 

 

 //懒汉式,延迟加载,用到时才加载,节约资源

 private static UserManager userManager=null;

 

 private UserManager(){}

 

 public static synchronized UserManager getInstance()

 {

  if(userManager==null)

  {

   userManager=new UserManager();

  }

 

  return userManager;

 }

 

 

 

7.         Httppostget 有什么区别?

使用GET方法时,查询字符串(键值对)被附加在URL地址后面一起发送到服务器,使用POST方法时,查询字符串在POST信息中单独存在,和HTTP请求一起发送到服务器

 

 

cell中关键代码展示:

 

1.添加longpress事件

 

[self addGestureRecognizer: [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longTap:)]];

 

2.处理长按事件

 

-(void)longTap:(UILongPressGestureRecognizer *)longRecognizer

{

  if (longRecognizer.state==UIGestureRecognizerStateBegan) {

    [self becomeFirstResponder];

    UIMenuController *menu=[UIMenuController sharedMenuController];

    UIMenuItem *copyItem = [[UIMenuItem alloc] initWithTitle:@"复制" action:@selector(copyItemClicked:)];

    UIMenuItem *resendItem = [[UIMenuItem alloc] initWithTitle:@"转发" action:@selector(resendItemClicked:)];

    [menu setMenuItems:[NSArray arrayWithObjects:copyItem,resendItem,nil]];

    [menu setTargetRect:self.bounds inView:self];

    [menu setMenuVisible:YES animated:YES];

  }

}

3.实现默认方法

 

#pragma mark 处理action事件

-(BOOL)canPerformAction:(SEL)action withSender:(id)sender{

  if(action ==@selector(copyItemClicked:)){

    return YES;

  }else if (action==@selector(resendItemClicked:)){

    return YES;

  }

  return [super canPerformAction:action withSender:sender];

}

#pragma mark  实现成为第一响应者方法

-(BOOL)canBecomeFirstResponder{

  return YES;

}

 

4.处理item点击事件

 

#pragma mark method

-(void)resendItemClicked:(id)sender{

  NSLog(@"转发");

  //通知代理

}

-(void)copyItemClicked:(id)sender{

  NSLog(@"复制");

  // 通知代理

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1.         UIResponderUIControl有什么不同?

UIResponder类:上承NSObject,下接UIView UIVIewController UIApplacation;响应点,压,滑;

UIControl类:上承UIView,下接UIButton等开关按钮;

主要区别在于:

前者,主要是响应某个动作,执行某个行为--

-(voidtouchesBegan:(NSSet*)touches withEvent:(UIEvent *)event

后者,在继承了前者的属性基础上,还能够相应某个动作,为某个对象,添加动作--

- (void) addTarget:(id)target action:(SEL)action forControlEvents(UIControlEvents)controlEvents

 

 

2.         系统单例有哪些?

系统的单例类:

UIApplication(应用程序实例)

NSNotificationCenter(消息中心):

NSFileManager(文件管理):

NSUserDefaults(应用程序设置):

NSURLCache(请求缓存)

NSHTTPCookieStorage(应用程序cookies):

 

3.         异步线程怎么传值给主线程?

dispatch_async(dispatch_get_global_queue(0, 0), ^{

// 处理耗时操作的代码块...

 

//通知主线程刷新

dispatch_async(dispatch_get_main_queue(), ^{

//回调或者说是通知主线程刷新,

});

 

});

 

 

例子:dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

    NSURL * url = [NSURL URLWithString:@"http://avatar.csdn.net/2/C/D/1_totogo2010.jpg"]; 

    NSData * data = [[NSData alloc]initWithContentsOfURL:url]; 

    UIImage *image = [[UIImage alloc]initWithData:data]; 

    if (data != nil) { 

        dispatch_async(dispatch_get_main_queue(), ^{ 

            self.imageView.image = image; 

         }); 

    } 

});

 

 

4.         各控件的继承关系





5.         通知中心使用场合

6.         响应者链条,如button点击事件,系统是怎么找到那个button


0 0
原创粉丝点击