iOS一些面试题

面试题整理

1. 简述OC中内存管理机制。与retain配对使用的方法是dealloc还是release,为什么?需要与alloc配对使用的方法是dealloc还是release,为什么?readwrite,readonly,assign,retain,copy,nonatomic 、atomic、strong、weak属性的作用?

OC的内存管理机制是引用计数, 与retain匹配的是release, 因为retain是引用计数+1, release是引用计数-1. alloc匹配的是dealloc, alloc是开辟内存空间, dealloc是销毁所开辟的内存, 有开辟就要有销毁. readWrite读写特性, 可读可写. readonly只读, 只有getter, 没有setter. assign一般用于基本数据类型和ID类型. copy拷贝, 一般用于 NSString. 分为深拷贝和浅拷贝, 深拷贝拷贝的是对象, 浅拷贝拷贝的是指针. nonatomic非原子性, 不考虑线程安全, 优点是效率高. atomic原子性, 有点是线程安全, 缺点是效率低. strong强引用, 和MRC下的retain一样. weak弱引用, 类似MRC下的assign. 但是要注意的是strong和weak都是修饰对象类型的属性的, 不能修饰基本数据类型. ARC下仍然使用assign修饰基本数据类型.

2. 类变量的@protected ,@private,@public,@package,声明各有什么含义?


@protected 该类和所有的子类中的方法可以直接访问这样的变量,这是默认的。@private被修饰的变量是私有的, 和继承的思想冲突. @public公有, 除了自己和子类中的方法外,也可以被其他类或者其他模块中的方法所访问。开放性最大。和封装思想冲突. @package只能在本包内使用, 不能跨包使用.

3. 线程是什么?进程是什么?二者有什么区别和联系?


进程是对正在运行的程序过程的抽象, 其实就是咱们程序本身. 线程是程序运行的基本单元(可以理解为一个进程中执行的代码片段), 进程可以认为是一个容器, 里面装的线程真正的在执行代码, 完成功能. 一个程序至少一个进程, 一个进程至少一个线程.

4. 谈谈你对多线程开发的理解?ios中有几种实现多线程的方法?


好处:1、使用线程可以把程序中占据时间长的任务放到后台去处理,如图片、视频的下载2、发挥多核处理器的优势,并发执行让系统运行的更快、更流畅,用户体验更好缺点:1、更多的线程需要更多的内存空间2、当多个线程对同一个资源出现争夺的时候要注意线程安全的问题。iOS有三种多线程编程的技术:1、NSThread(两种创建方式)2、NSOperationQueue
3、Grand Central Dispatch (GCD)

1. 线程同步和异步的区别?IOS中如何实现多线程的同步?


同步:一个线程要等待上一个线程执行完之后才能执行当前的线程,生活中的例子(上厕所)。异步:同时去做两件或者多件事。比如边听歌边看报。GCD线程同步, NSOperationQueue设置同时可运行Operation个数都可以实现多线程的同步.

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

本题的题意是以第一个出现的字母作为参照,只要之后出现相同的字母并且和第一个字母不相邻,那么就删除。为防止删除某些字符之后,把之前不相邻的重复字符串转化为相邻字符串,所以可以先用空格替换掉需要删除的字符,最后对数组里面的空格进行处理。

 -(void)removeRepeat:(NSString *)aNum
{

NSMutableArray *mArr = [[NSMutableArray alloc]initWithCapacity:10];
for (int i = 0;i < aNum.length;i++)
{
    [mArr addObject:[aNum substringWithRange:NSMakeRange(i,1)]];
}
NSLog(@"- %@", mArr);
[self compareNum:mArr];
NSLog(@"%@",mArr);

}
//比较是否相等
/-(NSMutableArray *)compareNum:(NSMutableArray *)mArr
{
int count = mArr.count;//重新定义了,count不会减一
for (int j = 0; j < count - 1; j++)
{
    for (int i = j; i < count - 1-1-1; i++)
    {
        NSLog(@" %@  %@",[mArr objectAtIndex:j],[mArr objectAtIndex:i + 2]);
        NSString *a = [mArr objectAtIndex:j];
        NSString *b = [mArr objectAtIndex:i+2];

        if ([a isEqualToString:b])
        {
            [mArr replaceObjectAtIndex:i + 2 withObject:@" "];
        }
    }
}

return mArr;
}

1. 获取一台设备唯一标识的方法有哪些?


MAC地址(物理地址),udid,广告标识IDFA-identifierForIdentifier
参考链接< http://www.2cto.com/kf/201308/237648.html >。以上的现在都不能用了. 现在都是keychain, open udid配合使用,

iOS类是否可以多继承?如果没有,那可以用其他方法实现吗?简述实现过程。


不可以,可以通过消息转发、delegate和protocol和类别来实现类似多继承。

堆和栈的区别?


栈区(stack)–由编译器自动分配释放,存放函数的参数值、局部变量的值。
先进后出堆区(heap)–一般由程序员分配释放。
先进先出全局区(静态区)
(static)–全局变量和静态变量。程序结束后由系统释放。
文字常量区–常量字符串存放在这里。程序结束后由系统释放。
程序代码区—存放函数体的二进制文件。

iOS本地数据存储都有哪几种方式?iOS如何实现复杂对象的存储?

NSKeyedArchiver(归档)采用归档的形式来保存数据,该数据对象需要遵守NSCoding协议,并且该对象对应的类必须提供encodeWithCoder:和initWithCoder:方法。
plist文件存储数据, NSUserDefaults实际的存储方式也是plist文件:用来保存应用程序设置和属性、用户保存的数据。用户再次打开程序或开机后这些数据仍然存在。NSUserDefaults可以存储的数据类型包括:NSData、NSString、NSNumber、NSDate、NSArray、NSDictionary。
Write写入方式:永久保存在磁盘中。
SQLite(FMDB)
CoreData切记coredata不是数据库, 他的存储核心思想是托管对象, 只是咱们经常用的存储文件为SQLite.还可以用XML, 二进制等方式.

iOS的动态性

1。动态类型。 如id类型。实际上静态类型因为其固定性和可预知性而使用得更加广泛。静态类型是强类型,而动态类型属于弱类型。运行时决定接收者。
2。 动态绑定。让代码在运行时判断需要调用什么方法,而不是在编译时。与其他面向对象语言一样,方法调用和代码并没有在编译时连接在一起,而是在消息发送时才进行连接。运行时决定调用哪个方法。
3。 动态载入。让程序在运行时添加代码模块以及其他资源。用户可以根据需要加载一些可执行代码和资源,而不是在启动时就加载所有组件。可执行代码中可以含有和程序运行时整合的新类。

写出方法获取ios内存使用情况。(不用看, 看了也写不出来)// 获取当前设备可用内存及所占内存的头文件

  #import <sys/sysctl.h>
  #import <mach/mach.h>

// 获取当前设备可用内存(单位:MB)
 - (double)availableMemory
{
vm_statistics_data_t vmStats;
mach_msg_type_number_t infoCount = HOST_VM_INFO_COUNT;
kern_return_t kernReturn = host_statistics(mach_host_self(), 
                                         HOST_VM_INFO, 
                                         (host_info_t)&vmStats, 
                                         &infoCount);

if (kernReturn != KERN_SUCCESS) {
return NSNotFound;
}

return ((vm_page_size *vmStats.free_count) / 1024.0) / 1024.0;
}

// 获取当前任务所占用的内存(单位:MB)
 - (double)usedMemory
{
 task_basic_info_data_t taskInfo;
 mach_msg_type_number_t infoCount = TASK_BASIC_INFO_COUNT;
 kern_return_t kernReturn = task_info(mach_task_self(), 
                                   TASK_BASIC_INFO, 
                                   (task_info_t)&taskInfo, 
                                   &infoCount);

if (kernReturn != KERN_SUCCESS
  ) {
return NSNotFound;
}

return taskInfo.resident_size / 1024.0 / 1024.0;}

深拷贝和浅拷贝的理解?


深拷贝拷贝的是内容,浅拷贝拷贝的是指针。深拷贝和浅拷贝最大的区别就是子类对象的地址是否改变,如果子类对象的地址改变那么就是深拷贝。

怎样实现一个singleton的类。 //+ (LOSingleton *) sharedInstance


{
static LOSingleton *sharedInstance = nil ;
static dispatch_once_t onceToken; // 锁
dispatch_once (& onceToken, ^ { // 最多调用一次
sharedInstance = [[LOSingleton alloc] init];
});
return sharedInstance;
}

RunLoop是什么?


一个RunLoop就是一个事件处理的循环,用来不停的调度工作以及处理输入时间。使用runloop的目的是让你的线程在有工作的时候忙于工作,而没工作的时候处于休眠状态。runloop的设计是为了减少cpu无谓的空转。每个开辟的线程都有一个Runloop, 主线程的Runloop时默认开启的, 咱们手动开辟的子线程Runloop是默认不开启的, 如果需要开启, 需要调用API[[NSRunloop currentRunloop] run]开启.最常见的需要开启Runloop的是在子线程里面调用for循环, 如果不开启runloop循环方法就不能正常执行.

什么是序列化和反序列化,可以用来做什么?如何在OC中实现复杂对象的存储?


如果你需要存储一个复杂的对象的话,经常要以二进制的方法序列化这个对象,这个过程叫Archiving。如果一个对象需要进行序列化,那么需要遵循NScoding协议,主要有两个方法:-(id)initWithCoder:(NSCoder*)coder;//从coder中读取数据,保存到相应变量中,即反序列化数据。-(void)encodeWithCoder:(NSCoder*)coder;//读取实例变量,并把这些数据写到coder中去,即序列化数据。

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


 #define kMIN(X,Y) ((X) > (Y)) ? (Y) :(X)

iphone os有没有垃圾回收机制?简单阐述一下OC内存管理。


iphone os没有垃圾回收机制。
垃圾回收机制用于在空闲时间以不定时的方式动态的回收无任何引用的对象占据的内存空间。OC内存管理机制看第一套题.
### 简述应用程序按Home键进入后台时的生命周期,以及从后台回到前台时的生命周期?
进入后台生命周期走:
- (void)applicationWillResignActive:(UIApplication *)application;
- (void)applicationDidEnterBackground:(UIApplication *)application;
回到前台生命周期走:
- (void)applicationWillEnterForeground:(UIApplication *)application;
- (void)applicationWillResignActive:(UIApplication *)application;

ViewController 的 alloc,loadView,

viewDidLoad,viewWillAppear,viewDidUnload,dealloc、init分别是在什么时候调用的?在自定义ViewController的时候这几个函数里面应该做什么工作?
- alloc初始化当前的ViewController
- loadView:没有正在使用nib视图页面,子类将会创建自己的自定义视图层
- viewDidLoad:试图被加载后调用
- viewWillAppear:试图即将出现的时候调用
- viewDidUnload:

这段代码有什么问题,如何修改

for (int i = 0; i < someLargeNumber; i++) { 
NSString *string = @”Abc”;
string = [string lowercaseString];
 string = [string stringByAppendingString:@"xyz"];
  NSLog(@“%@”, string);
 }

如果数字很大的话会造成内存一直增加(因为一直通过便利构造器方法创建autorelease对象),直到循环结束才减少,在循环内加一个自动释放池,更改后代码如下:

for (int i = 0; i < someLargeNumber; i++) { 
NSString *string = @”Abc”;@autoreleasepool {
string = [string lowercaseString];
string = [string stringByAppendingString:@"xyz"];
NSLog(@“%@”, string);

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

    NSString *string = @” 20 | http://www.baidu.com”;[string componentsSeparatedByString:@”|”];

4. 用obj-c写一个冒泡排序

NSMutableArray *array = [NSMutableArray arrayWithArray:@[@"3",@"1",@"10",@"5",@"2",@"7",@"12",@"4",@"8"]];
for (int i = 0; i < array.count; i ++) {
    for (int j = 0; j < array.count  - 1 - i; j++) {
        if ([[array objectAtIndex:j] integerValue] > [[array objectAtIndex:j + 1] integerValue]) {
            [array exchangeObjectAtIndex:j withObjectAtIndex:j + 1];
        }
    }
}
NSLog(@"%@", array);
  1. 简述你对UIView、UIWindow和CALayer的理解

UIView继承于UIResponder, UIResponder继承于NSObject,UIView可以响应用户事件。CALayer继承于NSObject,所以CALayer不能响应事件。UIView构建界面,UIView侧重于对内容的管理,CALayer侧重于对内容的绘制。UIView是用来显示内容的,可以处理用户事件;CALayer是用来绘制内容的,对内容进行动画处理,依赖与UIView来进行显示,不能处理用户事件。

  1. 面向对象的三大特征,并作简单的介绍封装、继承、多态。封装:是把客观事物封装成抽象的类,隐藏内部的实现,对外部提供接口。继承:可以使用现有类的所有功能,并且在无需重新编写原来的类的情况下对这些功能进行扩展。多态:不同的对象以自己的方式响应相同的的消息的能力叫做多态,或者说父类指针指向子类对象<如UITableView的,cellForRow方法,返回值类型是UITbaleViewCell,但是你返回的cell可以是你自定义的cell,在比如多个类里面都有同一个方法>
  2. 重写一个NSStrng类型的,retain方式声明name属性的setter和getter方法
  3. 简述NotificationCenter、KVC、KVO、Delegate?并说明它们之间的区别?Notification:观察者模式,观察者模式一般用于一对多, 发出消息者并不在意有没有\有多少个接收者, 只管发出消息. 观察者模式的效率低于代理模式. KVC键值编码,可以直接通过字符串的名字(key)或者路径来间接访问属性的机制,而不是通过调用getter和setter方法访问。
KVO:观测指定对象的属性,当指定对象属性的setter方法被调用之后会通知相应的观察者。
delegate:一对一,delegate遵循某个协议并实现协议声明的方法。
  4. What is lazy loading?懒加载,又称为延迟加载。通常用法,你有一个UITextField类 型的property,简单定义为userNameTextField,但是你不在初始化方法里为其alloc/init,它就只是一个指针,不会占用内 存。在访问器里判断此property的指针是否为空,若为空,就alloc/init,这时才真正生成这个对象除非这个对象被使用,否则它永远不会真正 生成,也就不会占用内存。
  5. 什么是Protocol?什么是代理?写一个委托的interface?委托的property声明用什么属性?为什么?协议提供了一组方法,但是并不负责实现,如果一个类遵循了某个协议,并且实现了协议里面的方法,那么我们称这个类就是遵循了某个协议的代理。属性的声明使用assign,防止出现循环引用的问题。
  6. 分别描述类别(categories)和延展(extensions)是什么?以及两者的区别?继承和类别在实现中有何区别?为什么Category只能为对象添加方法,却不能添加成员变量?category类目:在不知道源码的情况下为一个类扩展方法,extension:为一个类声明私有方法和变量。继承是创建了一个新的类,而类别只是对类的一个扩展,还是之前的类。类目的作用就是为已知的类添加方法。

  7. Objective-C有私有方法么?私有变量呢?如多没有的话,有没有什么代替的方法?objective-c 里面有私有方法, 但是没有绝对的私有方法, 有私有变量.@private来修饰私有变量

  8. #import、#include和@class有什么区别#include c语言中引入一个头文件,但是可能出现交叉编译, OC里面已经没有这个方式但如头文件了, 统一使用#import#import在OC中引入自己创建的头文件#import””或者系统框架#import<>。#import不会出现交叉编译@class对一个类进行声明,告诉编译器有这个类,但是类的定义什么的都不知道.
  9. 谈谈你对MVC的理解?为什么要用MVC?在Cocoa中MVC是怎么实现的?你还熟悉其他的OC设计模式或别的设计模式吗?MVC是Model-VIew-Controller,就是模型-视图-控制器, MVC把软件系统分为三个部分:Model,View,Controller。在cocoa中,你的程序中的每一个object(对象)都将明显地仅属于这三部分中的一个,而完全不属于另外两个。MVC可以帮助确保帮助实现程序最大程度的可重用性。各MVC元素彼此独立运作,通过分开这些元素,可以构建可维护,可独立更新的程序组建, 提高代码的重用性.单例模式,delegate设计模式,target-action设计模式
  10. 如监测系统键盘的弹出[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( ) name:UIKeyboardWillShowNotification object:nil];
    可以看看IQKeyboardManager这个第三方库.
  11. 举出5个以上你所熟悉的ios sdk库有哪些和第三方库有哪些?Foundation,CoreFraphics,UIKit,MapKit,CoreLocation,CFNetWork,MessageUI,ImageIO,CoreData,AFNetWorking,MKNetWorkKit,ASIHttpRequest,FMDB,ZXing,ZBar,SDWebImage
  12. 如何将产品进行多语言发布?程序的国际化
  13. 如何将敏感字变成**字符串替换stringByReplacingOccurrencesOfString: withString:
  14. objc中的减号与加号代表什么?+静态方法,也叫类方法,-实例方法, 当然也是运算符..
  15. 单例目的是什么,并写出一个?当一个类只能有一个实例的时候需要使用单例,也就是说这个类只有一个对象, 这个对象在程序运行期不释放, 可以用来记录数据,进行传值。创建参照第2个文件.
  16. 说说响应链当事件发生的时候,响应链首先被发送给第一个响应者(往往是事件发生的视图,也就是用户触摸屏幕的地方)。事件将沿着响应者链一直向下传递,直到被接受并作出处理。一般来说,第一响应这是个视图对象或者其子类,当其被触摸后事件就交由它处理,如果他不处理,时间就会被传递给视图控制器对象UIViewController(如果存在),然后是它的父视图对象(superview),以此类推直到顶层视图。接下来会沿着顶层视图(top view)到窗口(UIwindow 对象) 再到程序的(UIApplication对象),如果整个过程都没有响应这个事件,则该事件被丢弃,一般情况下,在响应链中只要有对象处理事件,事件就会被传递.

1、请写出代码,用blocks来取代上例中的protocol,并比较两种方法的优势。实际应用部分?请写出代码,用blocks取代协议或回调方法声明:

#import <Foundation/Foundation.h>
typedef void(^TestBlock)(NSString *string);
@interface LO_Person : NSObject
+ (void)showStringFromBlcok:(TestBlock)justBlock;@end实现:#import "LO_Person.h"

@implementation LO_Person

+ (void)showStringFromBlcok:(TestBlock)justBlock
{
NSString *str = @"测试blcok";
justBlock(str);
}@end调用:[LO_Person showStringFromBlcok:^(NSString *string) {
    NSLog(@"-- %@",string);
}];
  1. 你做iphone开发时候,有哪些传值方式,view和Controller之间是如何传值的?属性、delegate、block, 通知, 单例.
  2. 给定的一个字符串,判断字符串中是否还有png,有就删除它?[string stringByReplacingOccurrencesOfString:@”png” withString: @”“]
  3. 对于语句NSString* testObject = [[NSData alloc] init];testObject 在编译时和运行时分别是什么类型的对象?编译的时候是NSString类型,运行的时候是NSData类型
  4. OC中是所有对象间的交互是如何实现的?消息发送机制
  5. 目标-动作机制目标是动作消息的接收者。动作是控件发送给目标的消息,或者从目标的角度看,它是目标为了响应动作而实现的方法。常用的UIButton添加方法
  6. for(int index = 0; index < largenumber; index ++){NSString *tempStr = @”tempStr”;NSLog(tempStr);NSNumber *tempNumber = [NSNumber numberWithInt:2];NSLog(tempNumber);}这段代码有什么问题.?会不会造成内存泄露(多线程)?在内存紧张的设备上做大循环时自动释放池是写在循环内好还是循环外好?为什么?参照第三个文档
  7. 描述上拉加载、下拉刷新的实现机制?一般上拉加载和下拉刷新是使用在请求网络数据的时候, 根据下拉或者上拉的距离来判断是否进行网络请求, 当请求结束以后, 将收回上拉或者下拉的提示框.

21. 什么是沙盒(sandbox)?沙盒包含哪些文件,描述每个文件的使用场景。如何获取这些文件的路径?如何获取应用程序包中文件的路径?

iOS应用程序只能在为该改程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被成为沙盒,所以所有的非代码文件都要保存在此,例如图像,图标,声音,映像,属性列表,文本文件等。默认情况下,每个沙盒含有3个文件夹:Documents, Library 和 tmp。Documents:苹果建议将程序中建立的或在程序中浏览到的文件数据保存在该目录下,iTunes备份和恢复的时候会包括此目录Library:存储程序的默认设置或其它状态信息;
- Library/Caches:存放缓存文件,iTunes不会备份此目录,此目录下文件不会在应用退出删除
- tmp:提供一个即时创建临时文件的地方。
- iTunes在与iPhone同步时,备份所有的Documents和Library文件。iPhone在重启时,会丢弃所有的tmp文件。

  1. 谈谈对性能优化的看法,如何做?
    从用户体验出发:1、程序logging不要太长、2、相同数据不做重复获取、3、昂贵资源要重用(cell、sqlite、date),4、良好的编程习惯和程序设计:选择正确的集合对象和算法来进行编程、选择适合的数据存储格式(plist、SQLite)、优化SQLite查询语句5、数据资源方面的优化(缓存和异步加载)6. 永远不要一直请求M7协处理器几率的数据, 会造成设备发热.
    解决方案:
  2. 能够发现问题
  3. 利用log或工具分析问题原因
  4. 假设问题原因
  5. 改进代码和设计
    http://blog.csdn.net/yangxt/article/details/8173412

22. 应用程序如何省电?

  • 1:及时关闭定位.
  • 2不要频繁的请求网络,作本地存储.让用户主动的更新数据(上下拉刷新).
  • 3:提升程序的算法,优化代码,提高代码的质量.
  • 4:蓝牙, 需要才连接,用完及时断开.
  • 5:界面的渲染,(游戏中)尽量提升效率,减少渲染次数.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值