父类实现深拷贝时,子类如何实现深度拷贝。父类没有实现深拷贝时,子类如何实现深度拷贝。
•
深拷贝同浅拷贝的区别:浅拷贝是指针拷贝,对一个对象进行浅拷贝,相当于对指向对象的指针进行复制,产生一个新的指向这个对象的指针,那么就是有两个指针指向同一个对象,这个对象销毁后两个指针都应该置空。深拷贝是对一个对象进行拷贝,相当于对对象进行复制,产生一个新的对象,那么就有两个指针分别 指向两个对象。当一个对象改变或者被销毁后拷贝出来的新的对象不受影响。
•
实现深拷贝需要实现
NSCoying
协议,实现
- (
id
)copyWithZone:(NSZone *)zone
方法。当对一个
property
属性含有
copy
修饰符的时候,在进行赋值操作的时候实际上就是调用这个方法。
•
父类实现深拷贝之后,子类只要重写
copyWithZone
方法,在方法内部调用父类的
copyWithZone
方法,之后实现自己的属性的处理
•
父类没有实现深拷贝,子类除了需要对自己的属性进行处理,还要对父类的属性进行处理。
KVO
,
NSNotification
,
delegate
及
block
区别
• KVO
就是
cocoa
框架实现的观察者模式,一般同
KVC
搭配使用,通过
KVO
可以监测一个值的变化,比如
View
的高度变化。是一对多的关系,一个值的变化会通知所有的观察者。
• NSNotification
是通知,也是一对多的使用场景。在某些情况下,
KVO
和
NSNotification
是一样的,都是状态变化之后告知对方。
NSNotification
的特点,就是需要被观察者先主动发出通知,然后观察者注册监听后再来进行响应,比
KVO
多了发送通知的一步,但是其优 点是监听不局限于属性的变化,还可以对多种多样的状态变化进行监听,监听范围广,使用也更灵活。
• 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
方法
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
主队列
NSBlockOperation *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
;
}
如何重写类方法
• 1
、在子类中实现一个同基类名字一样的静态方法
• 2
、在调用的时候不要使用类名调用,而是使用
[
self class
]
的方式调用。原理,用类名调用是早绑定,在编译期绑定,用
[
self class
]
是晚绑定,在运行时决定调用哪个方法。
NSTimer
创建后,会在哪个线程运行。
•
用
scheduledTimerWithTimeInterval
创建的,在哪个线程创建就会被加入哪个线程的
RunLoop
中就运行在哪个线程
•
自己创建的
Timer
,加入到哪个线程的
RunLoop
中就运行在哪个线程。
id
和
NSObject
*的区别
•
id
是一个
objc_object
结构体指针,定义是
typedef struct
objc_object *
id
•
id
可以理解为指向对象的指针。所有
oc
的对象
id
都可以指向,编译器不会做类型检查,
id
调用任何存在的方法都不会在编译阶段报错,当然如果这个
id
指向的对象没有这个方法,该崩溃还是会崩溃的。
• NSObject *
指向的必须是
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
④
:
Theard
详解三种实现多线程的方式:
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.
深拷贝和浅拷贝的理解
.
深拷贝
;
拷贝的内容
.
浅拷贝
:
拷贝的指针
.
深拷贝如
:
NSMutableDictionary * 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,
这个宏输入两个参数并返回较小的一个
.
#define MIN(A,B) (A)>(B)?(B):(A)
17.
iPhone OS
有没有垃圾回收机制
,
简易阐述一下
OC
内存管理
.
木有
.
引用计数
,ARC
和
MRC,swift(
自动引用计数
).
18.
简述应用程序按
HOME
键进入后台时的生命周期
,
以及从后台进入前台时的生命周期
.
前者
:- (
void
)applicationWillResignActive:(UIApplication *)application
- (
void
)applicationDidEnterBackground:(UIApplication *)application
后者
:- (
void
)applicationWillEnterForeground:(UIApplication *)application
- (
void
)applicationDidBecomeActive:(UIApplication *)application
另
:
各个程序运行状态时代理的回调:
- (
BOOL
)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
告诉代理进程启动但还没进入状态保存
- (
BOOL
)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
告诉代理启动基本完成程序准备开始运行
- (
void
)applicationWillResignActive:(UIApplication *)application
当应用程序将要入非活动状态执行,在此期间,应用程序不接收消息或事件,比如来电话了
- (
void
)applicationDidBecomeActive:(UIApplication *)application
当应用程序入活动状态执行,这个刚好跟上面那个方法相反
- (
void
)applicationDidEnterBackground:(UIApplication *)application
当程序被推送到后台的时候调用。所以要设置后台继续运行,则在这个函数里面设置即可
- (
void
)applicationWillEnterForeground:(UIApplication *)application
当程序从后台将要重新回到前台时候调用,这个刚好跟上面的那个方法相反。
- (
void
)applicationWillTerminate:(UIApplication *)application
当程序将要退出是被调用,通常是用来保存数据和一些退出前的清理工作。这个需要要设置
UIApplicationExitsOnSuspend
的键值。
- (
void
)applicationDidFinishLaunching:(UIApplication*)application
当程序载入后执行
在上面
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:
视图将要出现时调用
.
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
死循环
27.
这段代码有什么问题
,
如何修改
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"
中,
"|"
字符前面和后面的数据,分别输出它们
。
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
];
40.
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.
热更新几种实现方式
67.
多线程的底层实现?
线程:进程中一个特立独行的控制单元(路径)。多线程:一个进程至少有一个线程,即主线程。
①、
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
内部怎么实现的
?
1 IOS和OS X的核心是XNU内核,GCD是基于XUN内核实现的
2 GCD的API全部在libdispatch库中
3 GCD的底层实现主要有Dispatch Queue 和Dispatch Source
Dispatch Queue :管理block操作
Dispatch Source :处理事件(比如线程间通信)
72.
怎么保证多人开发进行内存泄露检查。
使用
Analuze
进行代码的静态分析,为避免麻烦,多人开发尽量使用
ARC.
73
、非自动内存管理情况下怎么做单例模式。
创建一个单例对象的静态实例,并初始化为
nil
。
创建一个类的类工厂方法,当且仅当这个类的实例为
nil
时生成一个类的实例。
实现
NScopying
协议,覆盖
allocWithZone
:方法,确保用户在直接分配对象时,不会产生另一个对象。
覆盖
release
、
autorelease
、
retain
、
retainCount
方法,确保单例的状态。
74
、对于类方法(静态方法)默认是
autorelease
的,所有类方法都会这样吗?
①、系统自带的绝大数类方法返回的对象,都是经过
autorelease.
75
、
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.F
oundation
对象与
Core Foundation
对象有何区别?
Foundation
对象是
OC
的,
Core Foundation
对象是
C
对象。
数据类型之间的转换:
ARC
:
_bridge_retained
、
_bridge_transfer
非
ARC:_bridge
82
、不用第三变量,交换
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(
滤镜处理
)
能够调节图片的各种属性(对比度、色温、色差等)
86
、
NSNotification
和
KVO
的区别和用法是什么?什么时候应该使用通知,什么时候应该使用
KVO,
他们的实现有何区别?如果用
protocol
和
delegate
来实现类似的功能可能吗?可能的话有何问题?不可能的话
why
?
通知比较灵活,一个通知能被多个对象接受,一个对象可以接受多个通知。
代理不交规范,但是代码较多(默认是一对一)
KVO
性能不好(底层会产生新的类),只能监听某个对象属性的变化,不推荐使用。
87
、
block
内部的实现原理。
Objective-C
是对
C
语言的扩展,
block
的实现是基于指针和函数指针。
88
、怎么解决缓存池满的问题?
iOS
中不存在缓存池满的情况,通常在对象需要创建时才创建,比如
UITableView
中一般只会创建刚开始在屏幕中的
cell
,之后都是从缓存池里取,不会再创建新对象。
89
、
控制器
View
的生命周期及相关函数是什么?你在开发中是如何使用的?
1
、首先判断控制器是否有视图,如果没有就调用
loadView
方法创建:通过
storyBoard
或者代码。
2
、随后调用
viewDidLoad
,可以进行下一步的初始化操作,只会被调用一次。
3
、在视图显示之前调用
viewWillAppear,
该函数可以多次调用。
4
、视图
viewDidAppear
5
、在布局变化前后,调用
viewWill/DidLayoutSubViews
处理相关信息。
90
、
有些图片加载比较慢怎么处理?你是怎么优化程序的性能的?
①、图片下载放在异步线程。
②、图片下载过程使用占位图片。
③、如果图片比较大,可以使用多线程断点下载。
91.
App
需要加载大量数据,给服务器发送请求,但是服务器卡住了怎么办?
设置请求超时,给用户提示请求超时,根据用户操作再次请求。
92
、
SDWebImage
具体如何实现?
其实就是沙盒缓存机制,主要由三块组成:内存图片缓存,内存操作缓存,磁盘沙盒缓存。
①、利用
NSOperationQueue
和
NSOperation
下载图片,还使用了
GCD
(解析
GIF
图片)。
②、利用
URL
作为
key
,
NSOperation
作为
value.
③、利用
URL
作为
key
,
UIImage
作为
value
93
、
AFNetWorking
实现原理。
基于
NSURL.
采用
block
的方法处理请求,直接返回的是
json
、
XML
数据。
AFN
直接操作对象是
AFHTTPClient,
是一个实现了
NSCoding
和
NSCopying
协议的
NSObject
子类。
AFGTTPClient
是一个封装了一系列操作方法的工具类。
AFN
默认没有封装同步请求,如果开发者需要使用同步请求,需要重写相关的方法(
getPath:parameters:failure
),对
AFHTTPRequestOperation
进行同步处理。
9
4
、什么是响应链,它是怎么工作的?
9
5
、
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
6
、
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
协议
,
实现这个方法
,
在这里方法里对添加的手势进行处理就可以解决冲突
- (
BOOL
)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
9
7
、
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
8
、
+load
和
+initialize
的区别是什么?
+(
void
)load;
当类对象被引入项目时
, runtime
会向每一个类对象发送
load
消息
load
方法会在每一个类甚至分类被引入时仅调用一次
,
调用的顺序:父类优先于子类
,
子类优先于分类
load
方法不会被类自动继承
+(
void
)initialize;
也是在第一次使用这个类的时候会调用这个方法
9
9
、如何让
Category
支持属性?
使用
runtime
可以实现
头文件
@interface
NSObject (test)
@property
(nonatomic, copy) NSString *name;
@end
.m
文件
@implementation
NSObject (test)
定义关联的
key
static const char
*key =
"name"
;
- (NSString *)name
{
根据关联的
key
,获取关联的值。
return
objc_getAssociatedObject(
self
, key);
}
- (
void
)setName:(NSString *)name
{
第一个参数:给哪个对象添加关联
第二个参数:关联的
key
,通过这个
key
获取
第三个参数:关联的
value
第四个参数
:
关联的策略
objc_setAssociatedObject(
self
, key, name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
100
、
NSOperation
相比于
GCD
有哪些优势?
提供了在
GCD
中不那么容易复制的有用特性。
可以很方便的取消一个
NSOperation
的执行
可以更容易的添加任务的依赖关系
提供了任务的状态:
isExecuteing, isFinished.
101
、
strong / weak / unsafe_unretained
的区别?
weak
只能修饰
OC
对象
,
使用
weak
不会使计数器加
1,
对象销毁时修饰的对象会指向
nil
,
strong
等价与
retain,
能使计数器加
1,
且不能用来修饰数据类型
unsafe_unretained
等价与
assign,
可以用来修饰数据类型和
OC
对象
,
但是不会使计数器加
1,
且对象销毁时也不会将对象指向
nil
,
容易造成野指针错误
102
、如何为
Class
定义一个对外只读对内可读写的属性
?
在头文件中将属性定义为
readonly,
在
.m
文件中将属性重新定义为
readwrite
103
、
Objective-C
中,
meta-class
指的是什么?
meta-
class
是
Class
对象的类
,
为这个
Class
类存储类方法
,
当一个类发送消息时
,
就去那个类对应的
meta-
class
中查找那个消息
,
每个
Class
都有不同的
meta-
class
,
所有的
meta-
class
都使用基类的
meta-
class
(
假如类继承
NSObject,
那么他所对应的
meta-
class
也是
NSObject)
作为他们的类
104
、
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
来显示
105
、
+[UIView animateWithDuration:animations:completion:]
内部大概是如何实现的?
animateWithDuration:
这就等于创建一个定时器
animations:
这是创建定时器需要实现的
SEL
completion:
是定时器结束以后的一个回调
block
以上只是自己的理解
,
不一定正确
,
有对这个有研究的朋友请告知下
106
、
什么时候会发生「隐式动画」?
当改变
CALayer
的一个可做动画的属性,它并不能立刻在屏幕上体现出来
.
相反,它是从先前的值平滑过渡到新的值。这一切都是默认的行为,你不需要做额外的操作
,
这就是隐式动画
107
、
如何处理异步的网络请求?
异步请求:会单独开一个线程去处理网络请求,主线程依然处于可交互状态
,
程序运行流畅
POST
请求
创建
url
对象
NSURL *url = [NSURL URLWithString:urlString];
创建请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10];
创建参数字符串对象
NSString *parmStr = [NSString stringWithFormat:
@"
参数
"
];
将字符串转换为
NSData
对象
NSData *data = [parmStr dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:data];
[request setHTTPMethod:
@"POST"
];
创建异步连接
[NSURLConnection connectionWithRequest:request delegate:
self
];
然后实现代理方法
服务器接收到请求时
- (
void
)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
}
当收到服务器返回的数据时触发
,
返回的可能是资源片段
- (
void
)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
}
当服务器返回所有数据时触发
,
数据返回完毕
- (
void
)connectionDidFinishLoading:(NSURLConnection *)connection
{
}
请求数据失败时触发
- (
void
)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(
@"%s"
,
__FUNCTION__
);
}
108
、
frame
和
bounds
的区别是什么?
frame
相对于父视图
,
是父视图坐标系下的位置和大小。
bounds
相对于自身
,
是自身坐标系下的位置和大小。
frame
以父控件的左上角为坐标原点,
bounds
以自身的左上角为坐标原点
109
、如何把一张大图缩小为
1
/
4
大小的缩略图?
let data = UIImageJPEGRepresentation(image, 0.25)