父类实现深拷贝时,子类如何实现深度拷贝。父类没有实现深拷贝时,子类如何实现深度拷贝。ios
• 深拷贝同浅拷贝的区别:浅拷贝是指针拷贝,对一个对象进行浅拷贝,至关于对指向对象的指针进行复制,产生一个新的指向这个对象的指针,那么就是有两个指针指向同一个对象,这个对象销毁后两个指针都应该置空。深拷贝是对一个对象进行拷贝,至关于对对象进行复制,产生一个新的对象,那么就有两个指针分别 指向两个对象。当一个对象改变或者被销毁后拷贝出来的新的对象不受影响。程序员
• 实现深拷贝须要实现NSCoying协议,实现- (id)copyWithZone:(NSZone *)zone 方法。当对一个property属性含有copy修饰符的时候,在进行赋值操做的时候实际上就是调用这个方法。算法
• 父类实现深拷贝以后,子类只要重写copyWithZone方法,在方法内部调用父类的copyWithZone方法,以后实现本身的属性的处理sql
• 父类没有实现深拷贝,子类除了须要对本身的属性进行处理,还要对父类的属性进行处理。数据库
KVO,NSNotification,delegate及block区别编程
• KVO就是cocoa框架实现的观察者模式,通常同KVC搭配使用,经过KVO能够监测一个值的变化,好比View的高度变化。是一对多的关系,一个值的变化会通知全部的观察者。json
• NSNotification是通知,也是一对多的使用场景。在某些状况下,KVO和NSNotification是同样的,都是状态变化以后告知对方。NSNotification的特色,就是须要被观察者先主动发出通知,而后观察者注册监听后再来进行响应,比KVO多了发送通知的一步,可是其优 点是监听不局限于属性的变化,还能够对多种多样的状态变化进行监听,监听范围广,使用也更灵活。swift
• delegate 是代理,就是我不想作的事情交给别人作。好比狗须要吃饭,就经过delegate通知主人,主人就会给他作饭、盛饭、倒水,这些操做,这些狗都不须要关 心,只须要调用delegate(代理人)就能够了,由其余类完成所须要的操做。因此delegate是一对一关系。设计模式
• block是delegate的另外一种形式,是函数式编程的一种形式。使用场景跟delegate同样,相比delegate更灵活,并且代理的实现更直观。数组
• KVO通常的使用场景是数据,需求是数据变化,好比股票价格变化,咱们通常使用KVO(观察者模式)。delegate通常的使用场景是行为,需求是须要别人帮我作一件事情,好比买卖股票,咱们通常使用delegate。
Notification 通常是进行全局通知,好比利好消息一出,通知你们去买入。delegate是强关联,就是委托和代理双方互相知道,你委托别人买股票你就须要知道经纪人, 经纪人也不要知道本身的顾客。Notification是弱关联,利好消息发出,你不须要知道是谁发的也能够作出相应的反应,同理发消息的人也不须要知道 接收的人也能够正常发出消息。
将一个函数在主线程执行的4种方法
• GCD方法,经过向主线程队列发送一个block块,使block里的方法能够在主线程中执行。
dispatch_async(dispatch_get_main_queue(), ^{
须要执行的方法
});
• NSOperation 方法
mainQueue = [NSOperationQueue mainQueue]; 主队列
operation = [NSBlockOperation blockOperationWithBlock:^{须要执行的方法
}];
[mainQueue addOperation:operation];
• NSThread 方法
[self performSelector:@selector(method) onThread:[NSThread mainThread] withObject:nil waitUntilDone:YES modes:nil];
[self performSelectorOnMainThread:@selector(method) withObject:nil waitUntilDone:YES];
[[NSThread mainThread] performSelector:@selector(method) withObject:nil];
• RunLoop方法
[[NSRunLoop mainRunLoop] performSelector:@selector(method) withObject:nil];
如何让计时器调用一个类方法
• 计时器只能调用实例方法,可是能够在这个实例方法里面调用静态方法。
• 使用计时器须要注意,计时器必定要加入RunLoop中,而且选好model才能运行。scheduledTimerWithTimeInterval方法建立一个计时器并加入到RunLoop中因此能够直接使用。
• 若是计时器的repeats选择YES说明这个计时器会重复执行,必定要在合适的时机调用计时器的invalid。不能在dealloc中调用, 由于一旦设置为repeats 为yes,计时器会强持有self,致使dealloc永远不会被调用,这个类就永远没法被释放。好比能够在viewDidDisappear中调用,这 样当类须要被回收的时候就能够正常进入dealloc中了。
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];
-(void)timerMethod
{
调用类方法
[[self class] staticMethod];
}
-(void)invalid
{
[timer invalid];
timer = nil;
}
如何重写类方法
• 一、在子类中实现一个同基类名字同样的静态方法
• 二、在调用的时候不要使用类名调用,而是使用[self class]的方式调用。原理,用类名调用是早绑定,在编译期绑定,用[self class]是晚绑定,在运行时决定调用哪一个方法。
NSTimer建立后,会在哪一个线程运行。
• 用scheduledTimerWithTimeInterval建立的,在哪一个线程建立就会被加入哪一个线程的RunLoop中就运行在哪一个线程
• 本身建立的Timer,加入到哪一个线程的RunLoop中就运行在哪一个线程。
id和NSObject*的区别
id
• id能够理解为指向对象的指针。全部oc的对象 id均可以指向,编译器不会作类型检查,id调用任何存在的方法都不会在编译阶段报错,固然若是这个id指向的对象没有这个方法,该崩溃仍是会崩溃的。
指向的必须是NSObject的子类,调用的也只能是NSObjec里面的方法不然就要作强制类型转换。• 不是全部的OC对象都是NSObject的子类,还有一些继承自NSProxy。NSObject *可指向的类型是id的子集。
如下内容后续补充
iOS 核心框架
• CoreAnimation
• CoreGraphics
• CoreLocation
• AVFoundation
• Foundation
iOS核心机制
• UITableView 重用
• ObjC内存管理;自动释放池,ARC如何实现
• runloop
• runtime
• Block的定义、特性、内存区域、如何实现
• Responder Chain
• NSOperation
• GCD
数据结构
• 8大排序算法
• 二叉树实现
• 二分查找实现
面向对象编程
• 封装、继承、多态
• 设计模式6个原则
• 设计一个类的功能,如何划分粒度(单一职责)
• 接口隔离。
• 若是有一个鸟类,有飞的动做,一个鸵鸟继承它是合适的吗(里氏替换)
• 类之间的依赖如何依赖偶合度最小(依赖倒转)
高层依赖低层,低层不能依赖高层。依赖接口,不能依赖具体的类。
• 若是A要调用C函数,但C是B的成员类,应该如何设计?(迪米特法则)
• 如何设计类,能作到只增长代码,而不修改代码,有哪些经验(开放封闭)
经过设计模式解决。
计算机技术
• 计算机网络: TCP/IP、HTTPCDN、SPDY
• 计算机安全: RSA、AES、DES
• 操做系统:线程、进程、堆栈、死锁、调度算法
iOS新特性、新技术
• iOS7 UIDynamic、SpritKit、新布局、扁平化
• iOS8 应用程序扩展、HealthKit、SceneKit、CoreLocation、TouchID、PhotoKit
• iOS9
• Apple Watch
• 第三方库:SDWebImage、AFNetwork、JSONKit、wax
** 笔记 **
简述OC中内存管理机制.
答:内存管理机制:使用引用计数管理,分为ARC和MRC,MRC须要程序员本身管理内存,ARC则不须要.可是并非全部对象在ARC环境下均不须要管理内存,子线程和循环引用并非这样.与retain配对使用的是release,retain表明引用计数+1,release表明引用计数-1,当引用计数减为0时,对象则被系统自动销毁.与alloc配对使用的是dealloc,alloc表明为对象开辟内存空间,dealloc则表明销毁对象的内存空间.
2.readwrite,readonly,assign,retain,copy,nonatomic,atomic,strong,weak的做用?
答:读写属性:readonly和readwrite; 语义属性:assign/retain/copy; 原子性:nonatomic.
①.readwrite表明可读,可写,即有setter和getter方法,是默认属性.readonly表明只可读,即只有get方法,由于不会生成setter方法,因此它不能够和copy/retain/assign组合使用.
②.weak和assign均是弱引用,assign修饰基本数据类型,weak修饰对象类型.strong和weak用于ARC下(ARC下的代理使用weak,block块使用copy).strong至关于retain.weak至关于assign;assign/retain/copy这些属性用于指定set访问器的语义,也就是说,这些属性决定了以何种方式对数据成员赋值.
assign,直接赋值,引用计数不改变,适用于基本数据类型.
retain,浅拷贝,使用的是原来的内存空间,只能适用于Objective-C对象类型,而不能适用于Core Foundation对象(retain会增长对象的引用计数,而基本数据和Core Foundation对象都没有引用计数).
copy:对象的拷贝,新申请一块内存空间,并把原始内容复制到那片空间.新对象的引用计数为1,此属性只对那些遵循了NSCopy协议的对象类型有效.
③.nonatomic,非原子性访问,不加同步,是异步操做.默认为atomic,原子操做,atomic是Objc使用的一种线程保护技术,基本上来说,是防止在写未完成的时候被另一个线程读取,形成数据错误,而这种机制是消耗系统内存资源的,因此在移动端,都选择nonatomic.
3.内存分为5个区,分别是栈区,堆区,全局区,文字常量区,程序代码区.
栈区:由编译器自动分配释放,不须要管理内存.
堆区:通常有程序员分配释放.
全局区:存放全局变量和静态变量.
常量区:存放常量字符串.
代码区:存放二进制代码.
3.类变量的@protected,@private,@public,@package,声明各有什么含义?
@protected 受保护的.本类,子类可见.
@private 私有的,类内可用
@public 公有的,类内,子类,外部都可用
@package 可见度在@protected和@public之间,这个类型最经常使用于框架类的实例变量.
4.线程是什么?进程又是什么?区别和联系.
进程:正在运行的程序,负责程序的内存分配.
线程:线程是进程中一个独立执行的控制单元(路径),一个进程至少包含一条线程,即主线程.
建立线程的目的:开辟一条新的执行路径,运行指定的代码,与主线程的代码实现同时执行.
5.对多线程开发的理解,iOS中有几种实现多线程的方式.
多线程的使用场景:防止卡顿,能够同时完成多个任务,且不影响主线程,把耗时操做放在子线程中执行,可是会消耗内存.
实现多线程的方式:
①.NSThread(内存须要本身管理.触发),
②.NSOperationQueue(再也不关注线程,当前可执行任务个数queue.maxConcurrentOperationCount)
③.GCD
详解三种实现多线程的方式:
GCD:
GCD里面包含了串行队列、并行队列、主队列、全局队列。
Dispatch_queue_t q = dispatch_queue_create(“qqq”,DISPATCH_QUEUE_SERIAL);建立一个串行队列
Dispatch_sync(q,^{
});开启同步任务
Dispatch_async(q,^{
});开启异步任务
并行队列:DISPATCH_QUEUE_CONCURRENT
主队列:dispatch_queue_t q = dispatch_get_main_queue();
全局队列:dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
NSThread
获取当前线程:NSThread * current = [NSThread currentThread];
获取主线程:NSThread * main = [NSThread mainThread];
使用NSThread建立线程的两种方式:
(id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;
(void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;
暂停当前线程:
[NSThread sleepForTimeInterval:2];
NSOperationQueue
建立一个操做队列:NSOperationQueue * queue = [[NSOperationQueue alloc]init];
添加NSOperation到NSOperationQueue中:[queue addOperation:operation];
添加一组operation:[queue addOperations:operations waitUntilFinished:NO];
添加一个block形式的operation:[queue addOperationWithBlock:^(){
}];
添加NSOperation的依赖对象:[operation2 addDependency:operation1];
设置队列的最大操做数:[queue setMaxConcurrentOperationCount:1];
等待options完成:[operation waitUntilFinished];
暂停、继续queue:[queue setSuspended:YES] [queue setSuspend:NO]
6.线程同步和异步的区别?ios中如何实现线程的同步?
同步:任务顺序执行,下一个任务依赖于上一任务的完成.
异步:任务执行顺序不定,一块儿执行.
实现:设置依赖:NSOpreationQueue GCD中的串行队列.
7.iOS类是否能够多继承,若是没有,怎么实现?
不能够多继承.能够经过类目,延展,协议实现多继承.
类目:类目也叫分类,英文category,在没有原类.m文件的基础上,给该类添加方法.类目里不能添加实例变量,不能添加和原始类方法名相同的方法,不然会发生覆盖.一个类能够添加多个类目,类目中的方法能够成为原始类的一部分,和原始类方法级别相同,能够被子类继承.
延展:Extension,是一种特殊形式的类目,主要是在一个类的.m里面声明与实现.做用:就是给某类添加私有方法或者私有变量.
虽然延展是给一个类定义私有方法,可是OC没有绝对的私有方法,其实仍是能够调用的,延展里面声明的变量只能在该类内部使用,外界访问不了.若是是新建文件建的的某类延展.h文件,则不能添加实例变量,若是括号里没有类目名,则认为延展里面的方法为全都必须实现,若是有,则可选实现.
类目写的方法必须实现,延展写的方法非必须.
8.栈和堆的区别?
栈:内存系统管理(系统开辟,系统释放),先进后出.
堆:内存本身管理(本身开辟,本身释放).先进先出.
9.iOS本地数据存储都有几种方式?
①.NSkeyedArchiver:采用归档的形式来保存数据,该数据对象须要遵照NSCoding协议,而且该对象对应的类必须提供encodeWithCoder:和initWithCoder:方法.前一个方法告诉系统怎么对对象进行编码,然后一个方法则是告诉系统怎么对对象进行解码.
②.NSUserDefaults:用来保存应用程序设置和属性,用户保存的数据.用户再次打开程序或者开机后这些数据仍然存在.NSUserDefaults能够存储的数据类型包括:NSData,NSString,NSNumber,NSDate,NSArray.NSDictionary,其余类型的数据须要先行转换.
③.Write写入方式:永久保存在磁盘中.具体:a.得到文件保存的路径.b.生成该路径下的文件,c,往文件中写入数据.d.从文件中读出数据.
④.SQLite:采用SQLite数据库来存储数据,SQLite做为一种轻量级数据库.具体:a.添加SQLite相关的库以及头文件,b.使用数据库存数数据:打开数据库,编写数据库语句,执行,关闭数据库.另:写入数据库,字符串能够采用char方式,而从数据库中取出char类型,当char类型有表示中文字符时,会出现乱码,这是由于数据库默认使用ascII编码方式,因此想要正确从数据库中取出中文,须要使用NSString来接受从数据库取出的字符串.
⑤.CoreData:原理是对SQLite的封装,开发者不须要接触sql语句,就能够对数据库进行操做.
10.ios动态类型和动态绑定
多态:父类指针指向子类对象.
动态类型:只有在运行期,才能肯定其真正类型.
动态加载:根据不一样的条件,加载不一样的资源.32和64位.
11.深拷贝和浅拷贝的理解.
深拷贝;拷贝的内容.
浅拷贝:拷贝的指针.
深拷贝如:
dic = [@{} mutableCopy];
NSMutableArray
ary = [@[] mutableCopy];12.怎么实现一个单例的类.
单例是一种设计模式,对象只有一个.缺点:对象不会被释放,若是建立不少的话会占用不少内存,优势:能够当作工具类使用.
static SortDetailsModelDown * single = nil;
+(SortDetailsModelDown *)shareSortDetailsModelDown{
@synchronized(self){ if (!single) { single = [[SortDetailsModelDown alloc]init]; } } return single;
}
13.什么是安全释放?
先释放再置空.
14.RunLoop是什么?
事件循环,是线程里面的一个组件.主线程的RunLoop是自动开启的.分为:计时源(timer source),事件源(输入源):input source.防止CPU中断(保证程序执行的线程不会被系统终止).
Runloop提供了一种异步执行代码的机制,并不能并行执行任务,是事件接收和分发机制的一个实现.每个线程都有其对应的RunLoop,可是默认非主线程的RunLoop是没有运行的,须要为RunLoop添加至少一个事件源,而后run它.
通常状况下咱们是没有必要去启动线程的RunLoop的,除非你在一个单独的线程中须要长时间的检测某个事件.
RunLoop,正如其名所示,是线程进入和被线程用来响应事件以及调用事件处理函数的地方.
input source传递异步事件,一般是来自其余线程和不一样程序的消息.
timer source传递同步事件.
当有事件发生时,RunLoop会根据具体的事件类型通知应用程序做出响应.
当没有事件发生时,RunLoop会进入休眠状态,从而到达省电的目的.
当事件再次发生时,RunLoop会被从新唤醒,处理事件.
通常在开发中不多会主动建立RunLoop,而一般会把事件添加到RunLoop中.
15.什么是序列化和反序列化,能够用来作什么?如何在OC中实现复杂对象的存储.
序列化和反序列化:归档和反归档,进行本地化,进行数据存储.
CoreData:数据托管.有四种存储方式:xml,sqlite,二进制,内存.
遵循NSCoding协议以后,进行归档便可实现复杂对象的存储.
16.写一个标准宏MIN,这个宏输入两个参数并返回较小的一个.
17.iPhone OS 有没有垃圾回收机制,简易阐述一下OC内存管理.
木有.引用计数,ARC和MRC,swift(自动引用计数).
18.简述应用程序按HOME键进入后台时的生命周期,以及从后台进入前台时的生命周期.
前者:- (void)applicationWillResignActive:(UIApplication *)application
后者:- (void)applicationWillEnterForeground:(UIApplication *)application
另:
各个程序运行状态时代理的回调:
告诉代理进程启动但还没进入状态保存
告诉代理启动基本完成程序准备开始运行
当应用程序将要入非活动状态执行,在此期间,应用程序不接收消息或事件,好比来电话了
当应用程序入活动状态执行,这个恰好跟上面那个方法相反
当程序被推送到后台的时候调用。因此要设置后台继续运行,则在这个函数里面设置便可
当程序从后台将要从新回到前台时候调用,这个恰好跟上面的那个方法相反。
当程序将要退出是被调用,一般是用来保存数据和一些退出前的清理工做。这个须要要设置UIApplicationExitsOnSuspend的键值。
当程序载入后执行
在上面8个方法对应的方法中键入NSLog打印。
如今启动程序看看执行的顺序:
启动程序
lifeCycle[40428:11303] willFinishLaunchingWithOptions
lifeCycle[40428:11303] didFinishLaunchingWithOptions
lifeCycle[40428:11303] applicationDidBecomeActive
按下home键
lifeCycle[40428:11303] applicationWillResignActive
lifeCycle[40428:11303] applicationDidEnterBackground
双击home键,再打开程序
lifeCycle[40428:11303] applicationWillEnterForeground
lifeCycle[40428:11303] applicationDidBecomeActive
19.ViewController
alloc,loadView,viewDidLoad,viewWillAppear,viewDidUnload,dealloc,init分别是在何时调用?在自定义ViewController的时候这几个函数里面应该作什么工做?
alloc:申请内存时调用.
loadView:加载视图时调用.
viewDidLoad;视图已经加载后调用.
viewWillAppear:视图将要出现时调用.
viewDidUnload:视图已经加载可是没有加载出来时调用.
dealloc:销毁该视图时调用.
init;初始化该视图时调用.
20.描述应用程序的启动顺序.
a.程序入口main函数建立UIApplication实例和UIApplication代理实例.
b.在UIApplication代理实例中重写启动方法,设置根ViewController
c.在第一ViewController中添加控件,实现应用程序界面.
21.为何不少内置类如UITableViewControl的delegate属性都是assign而不是retain?
防止循环引用.
如:对象A引用了对象B,对象B引用了对象C,对象C引用了对象B,这个时候B的引用计数是2,而C的引用计数是1,当A再也不使用B的时候,就释放了B的全部权,这个时候C还引用对象B,因此B不会释放,引用计数为1,由于B也引用着对象C,B不释放,那么C也就不会被释放,因此他们的引用计数都为1,而且永远不会被释放,造成了循环引用.
22.使用UITableView的时候必需要实现的几种方法?
2个数据源方法.分别是:
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
(UITableViewCell )tableView:(UITableView )tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
23.写一个遍历构造器.
+(id)leftModelWith{
leftModel * model = [self alloc]init];
return model;
}
24.UIImage初始化一张图片有几种方法?简述其特色?
3种,
imageNamed:系统会先检查系统缓存中是否有该名字的image,若是有的话,则直接返回,若是没有,则先加载图像到缓存,而后再返回.
initWithContentsOfFile:系统不会检查缓存,而直接从文件系统中记载并返回.
imageWithCGImage:scale:orientation 当scale= 1的时候图像为原始大小,orientation指定绘制图像的方向.
25.person的retainCount值,并解释为何?
Person * per = [Person alloc]init];
self.person = per;
1或者2.看person是什么类型修饰的.
alloc+1,assign+0,retain+1.
26.下面这段代码有何问题?
@implementation Person
(void)setAge:(int)newAge {
self.age = newAge;
}
@end
死循环
这段代码有什么问题,如何修改
for (int i = 0; i < someLargeNumber; i++) {
NSString *string = @”Abc”;
string = [string lowercaseString];
string = [string stringByAppendingString:@"xyz"];
NSLog(@“%@”, string);
}
加入自动释放池@autoreleasepool{};
for (int i = 0; i < someLargeNumber; i++) {
@antoreleasepool {
NSString *string = @”Abc”;
string = [string lowercaseString]; string = [string stringByAppendingString:@"xyz"]; NSLog(@“%@”, string); }
}
28.截取字符串"20 | http://www.baidu.com"中,"|"字符前面和后面的数据,分别输出它们。
["20 | http://www.baidu.com " componentSeparatedByString:@"|"];
29.用obj-c 写一个冒泡排序.
NSMutableArray *ary = [@[@"1", @"2", @"3", @"4", @"6", @"5"] mutableCopy];
for (int i = 0; i < ary.count - 1; i++) {
for (int j = 0; j < ary.count - i - 1; j++) { if ([ary[j] integerValue] < [ary[j + 1] integerValue]) { [ary exchangeObjectAtIndex:j withObjectAtIndex:j + 1]; } }
}
NSLog(@"%@", ary);
30.简述对UIView.UIWindow和CALayer的理解.
UIWindow是应用的窗口,继承于UIResponder.
UIView继承于UIView,是建立窗口中的一个视图,能够响应交互事件.一个程序只有一个主window,能够有多个window.
CALayer图层,一个view可有多个图层,不能够响应事件.
31.写一个完整的代理,包括声明,实现.
代理:遵照协议的对象.
@class MyView;
第一步:指定协议:(协议名:类名+Delegate)
@protocol MyViewDelegate <NSObject>
@required
-(void)changeViewBackgroudColor:(MyView *)view;
@optional
-(void)test;
@end
@interface MyView : UIView
第二步:指定代理
@property (nonatomic,assign)id<MyView> delegate;
@end
第三步:代理遵循协议.
第四步:代理实现协议里面的必须实现的方法和其余可选方法.
第五步:委托方通知代理开始执行方法.
32.分析json.xml的区别,底层如何实现?
Json:键值对.数据小,不复杂.便于解析,有框架支持,适合轻量级传输.做为数据包个数传输的时候效率更高.
xml:标签套内容.xml数据两较大,比较复杂.适合大数据量的传输.xml有丰富的编码工具,好比:Dom4j,JDom.解析方式有两种,一是经过文芳模型解析,另一种遍历节点.
33.ViewController的didReceiveMemoryWarning是在何时被调用的?
1.当应用程序的内存使用接近系统的最大内存使用时,应用会向系统发送内存警告,这时候系统会调用方法向全部ViewController发送内存警告.
2.打开系统相机.
3.加载高清图片.
默认操做:把里面没有用的对象进行释放.
34.面向对象的三大特征,简单介绍.
封装:代码模块化,方便之后调用.
继承:子类继承父类的全部方法和属性.
多态:父类指针指向子类对象.
35.重写一个NSString类型的,retain方式声明name属性的setter和getter方法.
属性的三大特性:语义特性,原子特性,读写特性.
同时重写setter和getter方法,@synchronized name = _name,关联属性和实例变量.
(void)setName:(NSString *)name{
if(_name != name){
[_name retain]; [_name release]; _name = name;
}
}
(NSString *)name{
return [[_name retain]autorelease];
}
36.简述NotificationCenter.KVC,KVO,Delegate?并说明它们之间的区别?
NotificationCenter:消息中心.消息通知.
KVC:利用键-值间接访问类中的某个属性.
[self setValue:@"123" forKeyPath:@"name"];
NSLog(@"%@",[self valueForKeyPath:@"name"]);
KVO:利用键-路径间接访问类中的某个属性,也就是观察者模式(KVO+通知中心).基于KVC和通知中心,观察的是实例变量.
Delegate:用于多个类之间的传值.
37.What is lazy loading?
懒加载
38.对MVC的理解,好处?
MVC:是一种架构.model:数据处理,view:视图显示,controller:逻辑控制,负责视图和模型之间的通讯.
高类聚,低耦合,提升代码的复用性.
39.监测键盘的弹出.
通知.
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector() name:UIKeyboardWillShowNotification object:nil];
5个ios,sdk库和第三方库.
系统库:UIKit框架:负责应用程序的图形及事件驱动的关键基础,如:用户界面管理,图形和窗口支持.
Mapkit框架:地图.
Message UI框架:电子邮件
AV Foundation框架:可用于音频播放.
OpenAL框架:用于播放,可播放高质,高性能的网络音频
Core Data框架:将数据存储在SQLite数据库.
Core Media框架:播放视频.
第三方:SDWebImage :简化图片处理
ShareSDK 分享
SVProgressHUD 轻量级菊花
AFNetworkin 方便网络开发
FreeStreamer 播放音频
41.介绍响应者链.
当用户点击屏幕,可以产生响应的对象组成的链.
继承自NSResponder,响应者链可以中断.
42.传值方式:
通知,单例,代理,属性,block.
43.NSString * test = [[NSData alloc] init],test在编译时和运行时分别是什么类型的对象?
编译时是NSString,运行时是NSData.NSData
44.OC中对象的交互是如何实现的?
消息机制.
45.给定一个字符串,判断字符串中是否还有png,有就删除.
stringContains,使用@""直接替换实现删除
46.目标-动做机制.
Target - action
47.什么是沙盒?沙盒里包含哪些文件,如何获取文件路径.
沙盒:程序可操做的磁盘空间,系统为之开辟.
包含了3个文件夹.
1.Documents:存放一些比较重要的文件,可是放入Documents中的文件不能过大.
2.Library :是一个资源库,存储一些不过重要的数据.里面包含了两个子文件夹,Caches文件夹,用于缓存,
Preferences文件夹,系统偏好设置,用户对应用程序的设置,如密码.perferences路径没法找到,只能经过NSUserDefaults.
如:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
48.介绍一下XMPP?
基于XML的点对点通信协议,实现通信功能.
优势:能够跨平台开发.
缺点:丢包,只能发文字(图片发送发的是连接).
49.应用程序如何省电?
获取请求不能过频.优化算法.
50.写一个递归方法,计算n的阶乘.
-(NSInteger)digui:(NSInteger)i{
if (i>0) { return i*[self digui:(i-1)]; }else{ return 1; }
}
[[NSUserDefaults standardUserDefaults]setObject:@([self digui:3]) forKey:@"value"];
51.NSArray 和 NSMutableArray 的区别?多线程下那个更安全.
NSArray: 不可变数组.
NSMutableArray: 可变数组.
多线程下NSArray更安全.
52.取出一个数组中的重复元素.
1.放进集
2.遍历删除
3.放进字典做为key,再取出key
54.isKindOfClass,isMemberOfClass做用分别是什么?
isKindOfClass是某个类的实例或者子类的实例.
isMemberOfClass是某个类的实例
55.请分别写出SEL,id的意思?
SEL:选择器.
id:范类型
OC中的对象就是C语言的指针.
56.iPhone上,能被应用程序直接调用的系统程序是什么?
能:相册,相机,通信录,音乐.
不能:计算器,天气,日历,指南针.
57.以.mm为扩展名的文件里,能够包含哪些代码?
C++,C,OC
58.说说后台如何运行程序.
在plist配置Application does not run in background设置NO(默认就是NO)的前提下.
添加required background modes,值是App registers for location updates和App plays auto or streams audio/video using AirPlay
59.sizeof和strlen的区别和联系?
sizeof:占用空间大小.
strlen:字符串大小.
60.sprintf,strcpy,memcpy的功能?使用上要注意哪些地方?
sprintf:将某些类型转换成字符串类型
strcpy:拷贝字符串,会越界,'/0'
memcpy:拷贝内存
61.写一个函数实现strlen的功能?
int sl(const char *s)
{
int length = 0; while (*s!='') { s++; length++; } return length;
}
62.写一个代码片实现输入一个字符串"20130322152830",输出一个NSDate类型的对象,打印该对象输出2013-03-11 15:28:32
NSString * str = @"20130322152832";
NSDateFormatter * format = [[NSDateFormatter alloc]init];
format.dateFormat = @"yyyyMMddHHmmss";//设置格式
NSLog(@"%@",[[format dateFromString:str] dateByAddingTimeInterval:8 60 60]);
63.用变量a写出如下定义
a、一个整型数int a = 10
b、一个指向整型数的指针int *p = 10
c、一个指向指针的指针,它指向的指针是指向一个整型数int **p =10
d、一个有10个整型数的数组 int a[10]
e、一个有10个指针的数组,该指针是指向一个整型数的int *a[10]
f、一个指向有10个整型数数组的指针int *a = {1,2,3,4,5,6,7,8,9,10};
g、一个指向函数的指针,该函数有一个整型参数,并返回一个整型数
int *a(int b){
return b;
}
64.cocoa和 cocoa touch?
cocoa包含Foundation和AppKit框架,可用于开发Mac OS X系统的应用程序
cocoa touch包含Foundation和UIKit框架,可用于开发iPhone OS 系统的应用程序
Cocoa时Mac OS X的开发环境,cocoa Touch是 Iphone OS的开发环境
65.网络从下往上分为几层?
从下往上:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。
IP 协议对应网络层,TCP 协议对应传输层,HTTP 协议对应于应用层。
socket 则是对 TCP/IP协议的封装和应用。也能够说,TCP/IP协议是传输层协议,主要解决数据如何在网络中传输,而 HTTTP 是应用层协议,主要解决
66.热更新几种实现方式
http://www.jianshu.com/p/8cec322531ae67.多线程的底层实现?
线程:进程中一个特立独行的控制单元(路径)。多线程:一个进程至少有一个线程,即主线程。
①、Mach 是第一个以多线程方式处理任务的系统,所以多线程的底层实现机制就是基于 Mach 的线程。
②、开发中不多用到 Mach 级的线程,由于 Mach级的线程没有提供多线程的基本特征,线程之间是独立的。
④、开发中实现多线程的方案:
NSThread、GCD、NSOperationQueue.NSOperation
68.线程之间怎么通讯?
①.performSelect:onThread:withObject:waitUntilDone:
②.NSMachPort
69.网络图片问题中怎么解决一个相同的网络地址重复请求的问题.
利用字典:图片地址为 key, 下载操做为 value.value
70.用 NSOperation和 NSOperationQueue处理 A.B.C三个线程,要求执行完 A.B 后才能执行?
建立队列
NSOperationQueue * queue = [[NSOperationQueue alloc]init];
建立三个操做
NSOperation * A = [NSBlockOperation blockOperationWithBlock:^{
NSLog{@"A"};
}];
NSOperation * B = [NSBlockOperation blockOperationWithBlock:^{
NSLog{@"B"};
}];
NSOperation * C = [NSBlockOperation blockOperationWithBlock:^{
NSLog{@"C"};
}];
添加依赖
[C addDependency:a];
[C addDependency:b];
执行操做
[queue addOperation:a];
[queue addOperation:b];
[queue addOperation:c];
71.GCD内部怎么实现的?
①.iOS和 OSX 的核心是 XNU 内核, GCD是基于 XNU 内核实现的(是由苹果电脑发展起来的操做系统内核).
②.GCD 的 API 所有在 libdispatch 库中.
③.GCD 底层实现主要有 Dispatch Queue(管理 block)和 Dispatch Source(处理事件).
72.怎么保证多人开发进行内存泄露检查。
使用Analuze进行代码的静态分析,为避免麻烦,多人开发尽可能使用ARC.
7三、非自动内存管理状况下怎么作单例模式。
建立一个单例对象的静态实例,并初始化为nil。
建立一个类的类工厂方法,当且仅当这个类的实例为nil时生成一个类的实例。
实现NScopying协议,覆盖allocWithZone:方法,确保用户在直接分配对象时,不会产生另外一个对象。
覆盖release、autorelease、retain、retainCount方法,确保单例的状态。
7四、对于类方法(静态方法)默认是autorelease的,全部类方法都会这样吗?
①、系统自带的绝大数类方法返回的对象,都是通过autorelease.
7五、block在ARC中和MRC中的方法有何区别?须要注意什么?
①.对于没有引用外部变量的Block,不管在ARC仍是MRC下,类型都是 NSGlobalBlock ,这种类型的block能够理解为一种全局的block,不须要考虑做用域的问题。同时,对它进行Copy和Retain操做也是无效的。
②.避免循环引用。
根据isa指针,block一共有3种类型的block
_NSConcreteGlobalBlock 全局静态
_NSConcreteStackBlock 保存在栈中,出函数做用域就销毁
_NSConcreteMallocBlock 保存在堆中,retainCount == 0销毁
76.什么状况下会发生内存泄露和内存溢出?
当程序在申请内存后,没法释放已经申请的内存空间(例如一个对象或者变量在用完后没有释放,这个对象就一直占用着内存),一次内存泄露能够忽略,但若是泄露过多的话,就会形成内存溢出。
当程序在申请内存时,但存入了更大的数据,出现内存溢出。
77.[NSArray arrayWithobject<id>]这个方法添加对象后,须要对这个数组进行释放操做吗?
不须要,这个对象会被放到自动释放池中。
78.自动释放池如何实现?
自动释放池以栈的形式实现,当你建立一个新的自动释放池时,它将被添加到栈顶,当一个对象收到发送autorelease消息时,它将添加到当前线程的处于栈顶的自动释放池中,当自动释放池被回收时,它们从栈中被删除而且会给池子里全部对象都作一次release操做。
79.KVO内部实现原理?
①.KVO是基于runtime机制实现的。
②.当某个类的对象第一次被观察时,系统就会在运行期动态的建立该类的一个派生类,在这个派生类中重写基类中任何被观察属性的setter方法。
派生类在被重写setter方法中实现了真正的通知机制。(Person->NSKVONotification Person)
80.可否把比较耗时的操做放在NSNotificationCenter中。
若是在异步线程发出的通知,那么就能够把耗时操做放到NSNotificationCenter中
若是在主线程发的通知,那么就不能够把耗时操做放到NSNotificationCenter中。
81.Foundation对象与Core Foundation对象有何区别?
Foundation对象是OC的,Core Foundation对象是C对象。
数据类型之间的转换:
ARC:_bridge_retained、_bridge_transfer
非ARC:_bridge
8二、不用第三变量,交换AB的值。
A=A+B
B=A-B
A=A-B
或者
A=A^B
B=A^B
A=A^B
83.简单描述下对单例模式设计的理解?
节省内存资源,一个应用就一个对象。
84.runtime实现的机制是什么?怎么用,通常用于干吗。
运行时机制,runtime库里面包含了跟类、成员变量、方法相关的API,好比获取类里面的全部成员变量,为类动态添加成员变量、动态改变类的方法实现,为类动态添加新的方法等,须要导入<objc/message.h><objc/message.h>
①.runtime,运行时机制,它是一套C语言库。
②.实际上咱们编写的全部OC代码,最终都是转换成为了runtime库的东西,好比类转换成了runtime库里面的结构体等数据类型,方法转换成了runtime库里面的C语言函数,平时调方法都是转成了objc_msgSend函数(因此说OC有个消息发送机制)
③、所以,能够说runtime是OC的底层实现,是OC的幕后执行者。
④、有了runtime库,能作什么呢?能够获取类里面的全部成员变量、为类动态的添加成员变量、动态的改变类的方法实现、为类动态添加新的方法等等。
85.是否使用Core Text 或者 Core Image ?
Core Text
随意修改文本的样式
图文混排(纯C语言)
Core Image(滤镜处理)
可以调节图片的各类属性(对比度、色温、色差等)
8六、NSNotification和KVO的区别和用法是什么?何时应该使用通知,何时应该使用KVO,他们的实现有何区别?若是用protocol和delegate来实现相似的功能可能吗?可能的话有何问题?不可能的话why?
通知比较灵活,一个通知能被多个对象接受,一个对象能够接受多个通知。
代理不交规范,可是代码较多(默认是一对一)
KVO性能很差(底层会产生新的类),只能监听某个对象属性的变化,不推荐使用。
8七、block内部的实现原理。
Objective-C是对C语言的扩展,block的实现是基于指针和函数指针。
8八、怎么解决缓存池满的问题?
iOS中不存在缓存池满的状况,一般在对象须要建立时才建立,好比UITableView中通常只会建立刚开始在屏幕中的cell,以后都是从缓存池里取,不会再建立新对象。
8九、控制器View的生命周期及相关函数是什么?你在开发中是如何使用的?
一、首先判断控制器是否有视图,若是没有就调用loadView方法建立:经过storyBoard或者代码。
二、随后调用viewDidLoad,能够进行下一步的初始化操做,只会被调用一次。
三、在视图显示以前调用viewWillAppear,该函数能够屡次调用。
四、视图viewDidAppear
五、在布局变化先后,调用viewWill/DidLayoutSubViews处理相关信息。
90、有些图片加载比较慢怎么处理?你是怎么优化程序的性能的?
①、图片下载放在异步线程。
②、图片下载过程使用占位图片。
③、若是图片比较大,可使用多线程断点下载。
91.App须要加载大量数据,给服务器发送请求,可是服务器卡住了怎么办?
设置请求超时,给用户提示请求超时,根据用户操做再次请求。
9二、SDWebImage具体如何实现?
其实就是沙盒缓存机制,主要由三块组成:内存图片缓存,内存操做缓存,磁盘沙盒缓存。
①、利用NSOperationQueue和NSOperation下载图片,还使用了GCD(解析GIF图片)。
②、利用URL做为key,NSOperation做为value.
③、利用URL做为key,UIImage做为value
9三、AFNetWorking实现原理。
基于NSURL.采用block的方法处理请求,直接返回的是json、XML数据。AFN直接操做对象是AFHTTPClient,是一个实现了NSCoding和NSCopying协议的NSObject子类。AFGTTPClient是一个封装了一系列操做方法的工具类。AFN默认没有封装同步请求,若是开发者须要使用同步请求,须要重写相关的方法(getPath:parameters:failure),对AFHTTPRequestOperation进行同步处理。
9四、什么是响应链,它是怎么工做的?
http://www.jianshu.com/p/9179e5d780c89五、iOS 的沙盒目录结构是怎样的? App Bundle 里面都有什么?
1.沙盒结构
Application:存放程序源文件,上架前通过数字签名,上架后不可修改
Documents:经常使用目录,iCloud备份目录,存放数据,这里不能存缓存文件,不然上架不被经过
Library
Caches:存放体积大又不须要备份的数据,SDWebImage缓存路径就是这个
Preference:设置目录,iCloud会备份设置信息
tmp:存放临时文件,不会被备份,并且这个文件下的数据有可能随时被清除的可能
2.App Bundle 里面有什么
Info.plist:此文件包含了应用程序的配置信息.系统依赖此文件以获取应用程序的相关信息
可执行文件:此文件包含应用程序的入口和经过静态链接到应用程序target的代码
资源文件:图片,声音文件一类的
其余:能够嵌入定制的数据资源
iOS 的签名机制大概是怎样的?
假设,咱们有一个APP须要发布,为了防止中途篡改APP内容,保证APP的完整性,以及APP是由指定的私钥发的。首先,先将APP内容经过摘要算法,获得摘要,再用私钥对摘要进行加密获得密文,将源文本、密文、和私钥对应的公钥一并发布便可。那么如何验证呢?
验证方首先查看公钥是不是私钥方的,而后用公钥对密文进行解密获得摘要,将APP用一样的摘要算法获得摘要,两个摘要进行比对,若是相等那么一切正常。这个过程只要有一步出问题就视为无效。
iOS 7的多任务添加了哪两个新的 API? 各自的使用场景是什么?
后台获取(Background Fetch):后台获取使用场景是用户打开应用以前就使app有机会执行代码来获取数据,刷新UI。这样在用户打开应用的时候,最新的内容将已然呈如今用户眼前,而省去了全部的加载过程。
推送唤醒(Remote Notifications):使用场景是使设备在接收到远端推送后让系统唤醒设备和咱们的后台应用,并先执行一段代码来准备数据和UI,而后再提示用户有推送。这时用户若是解锁设备进入应用后将不会再有任何加载过程,新的内容将直接获得呈现。
9六、UIScrollView 大概是如何实现的,它是如何捕捉、响应手势的?
我对UIScrollView的理解是frame就是他的contentSize,bounds就是他的可视范围,经过改变bounds从而达到让用户误觉得在滚动,如下是一个简单的UIScrollView实现
在头文件定义一个contentSize属性
@interface MyScrollView : UIView
@property (nonatomic) CGSize contentSize;
@end
@implementation MyScrollView
(instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self == nil) {
return nil;
}
添加一个滑动手势
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panGesture:)];
[self addGestureRecognizer:pan];
return self;
}
(void)panGesture:(UIPanGestureRecognizer *)gestureRecognizer{
改变bounds
CGPoint translation = [gestureRecognizer translationInView:self];
CGRect bounds = self.bounds;
CGFloat newBoundsOriginX = bounds.origin.x - translation.x;
CGFloat minBoundsOriginX = 0.0;
CGFloat maxBoundsOriginX = self.contentSize.width - bounds.size.width;
bounds.origin.x = fmax(minBoundsOriginX, fmin(newBoundsOriginX, maxBoundsOriginX));
CGFloat newBoundsOriginY = bounds.origin.y - translation.y;
CGFloat minBoundsOriginY = 0.0;
CGFloat maxBoundsOriginY = self.contentSize.height - bounds.size.height;
bounds.origin.y = fmax(minBoundsOriginY, fmin(newBoundsOriginY, maxBoundsOriginY));
self.bounds = bounds;
[gestureRecognizer setTranslation:CGPointZero inView:self];
}
第二个问题我的理解是解决手势冲突,对本身添加的手势进行捕获和响应
让UIScrollView遵照UIGestureRecognizerDelegate协议,实现这个方法,在这里方法里对添加的手势进行处理就能够解决冲突
9七、Objective-C 如何对已有的方法,添加本身的功能代码以实现相似记录日志这样的功能?
这题目主要考察的是runtime如何交换方法
先在分类中添加一个方法,注意不能重写系统方法,会覆盖
(NSString *)myLog
{
这里写打印行号,什么方法,哪一个类调用等等
}
而后交换方法
加载分类到内存的时候调用
(void)load
{
获取imageWithName方法地址
Method description = class_getClassMethod(self, @selector(description));
获取imageWithName方法地址
Method myLog = class_getClassMethod(self, @selector(myLog));
交换方法地址,至关于交换实现方式
method_exchangeImplementations(description, myLog);
}
9八、+load 和 +initialize 的区别是什么?
+(void)load;
当类对象被引入项目时, runtime 会向每个类对象发送 load 消息
load 方法会在每个类甚至分类被引入时仅调用一次,调用的顺序:父类优先于子类, 子类优先于分类
load 方法不会被类自动继承
+(void)initialize;
也是在第一次使用这个类的时候会调用这个方法
9九、如何让 Category 支持属性?
使用runtime能够实现
头文件
@interface NSObject (test)
@property (nonatomic, copy) NSString *name;
@end
.m文件
@implementation NSObject (test)
定义关联的key
static const char *key = "name";
100、NSOperation 相比于 GCD 有哪些优点?
提供了在 GCD 中不那么容易复制的有用特性。
能够很方便的取消一个NSOperation的执行
能够更容易的添加任务的依赖关系
提供了任务的状态:isExecuteing, isFinished.
10一、strong / weak / unsafe_unretained 的区别?
weak只能修饰OC对象,使用weak不会使计数器加1,对象销毁时修饰的对象会指向nil,strong等价与retain,能使计数器加1,且不能用来修饰数据类型
unsafe_unretained等价与assign,能够用来修饰数据类型和OC对象,可是不会使计数器加1,且对象销毁时也不会将对象指向nil,容易形成野指针错误
10二、如何为 Class 定义一个对外只读对内可读写的属性?
在头文件中将属性定义为readonly,在.m文件中将属性从新定义为readwrite
10三、Objective-C 中,meta-class 指的是什么?
meta-class 是 Class 对象的类,为这个Class类存储类方法,当一个类发送消息时,就去那个类对应的meta-class中查找那个消息,每一个Class都有不一样的meta-class,全部的meta-class都使用基类的meta-class(假如类继承NSObject,那么他所对应的meta-class也是NSObject)做为他们的类
10四、UIView 和 CALayer 之间的关系?
UIView显示在屏幕上归功于CALayer,经过调用drawRect方法来渲染自身的内容,调节CALayer属性能够调整UIView的外观,UIView继承自UIResponder,CALayer不能够响应用户事件
UIView是iOS系统中界面元素的基础,全部的界面元素都继承自它。它内部是由Core Animation来实现的,它真正的绘图部分,是由一个叫CALayer(Core Animation Layer)的类来管理。UIView自己,更像是一个CALayer的管理器,访问它的根绘图和坐标有关的属性,如frame,bounds等,实际上内部都是访问它所在CALayer的相关属性
UIView有个layer属性,能够返回它的主CALayer实例,UIView有一个layerClass方法,返回主layer所使用的类,UIView的子类,能够经过重载这个方法,来让UIView使用不一样的CALayer来显示
10五、+[UIView animateWithDuration:animations:completion:] 内部大概是如何实现的?
animateWithDuration:这就等于建立一个定时器
animations:这是建立定时器须要实现的SEL
completion:是定时器结束之后的一个回调block
以上只是本身的理解,不必定正确,有对这个有研究的朋友请告知下
10六、何时会发生「隐式动画」?
当改变CALayer的一个可作动画的属性,它并不能马上在屏幕上体现出来.相反,它是从先前的值平滑过渡到新的值。这一切都是默认的行为,你不须要作额外的操做,这就是隐式动画
10七、如何处理异步的网络请求?
异步请求:会单独开一个线程去处理网络请求,主线程依然处于可交互状态,程序运行流畅
POST请求
urlString = @"www.baidu.com";
建立url对象
url = [NSURL URLWithString:urlString];建立请求
request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10];
建立参数字符串对象
parmStr = [NSString stringWithFormat:@"参数"];将字符串转换为NSData对象
NSData *data = [parmStr dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:data];
[request setHTTPMethod:@"POST"];
建立异步链接
[NSURLConnection connectionWithRequest:request delegate:self];
而后实现代理方法
服务器接收到请求时
10八、frame 和 bounds 的区别是什么?
frame相对于父视图,是父视图坐标系下的位置和大小。bounds相对于自身,是自身坐标系下的位置和大小。
frame以父控件的左上角为坐标原点,bounds以自身的左上角为坐标原点
10九、如何把一张大图缩小为1/4大小的缩略图?
let data = UIImageJPEGRepresentation(image, 0.25)