Runtime视频
https://yunpan.cn/OcPcBAPbezTdzp
开场
- 详细介绍自己做过的最有成就感的一个项目
- 最近在读什么哪本书?
- 是否有过创业经历或者有过类似的想法?
- 为什么会参加竞赛,过程中的收获是什么?
- 是否参与过开源项目,收获是什么?
- 商场里买100元的东西会返80元代金元实际折扣是多少
- 四个人夜间要过一座桥,每人走路速度不一样,过桥需要时间分别是1,2,5,10
分钟。现在只有一只手电筒在过桥时必须带,同时只能两人过,如何安排能够让四
人最快速度过桥? - 25匹马赛跑,每次只能跑5匹,最快能赛几次找出跑得最快的3匹马?
- 如果你变成硬币那么小,然后被扔进一个搅拌机里,你将如何脱身
知识性问题
- 1.什么是响应链,它是怎么工作的?
- 2.如何访问并修改一个类的私有属性?
通过KVC和Runtime访问和修改私有属性
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property(nonatomic,copy)NSString *name;
@property(nonatomic,strong)NSString *age;
@property (nonatomic, copy) NSString * height;
@property (nonatomic, copy) NSString * sex;
@end
--------------------------------------------------------
#import <Foundation/Foundation.h>
#import "Person.h"
#import <objc/runtime.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
//KVC访问私有成员属性
Person *person = [[Person alloc]init];
[person setValue:@"m" forKey:@"name"];
[person setValue:@"18" forKey:@"age"];
NSString *name = [person valueForKey:@"name"];
NSString *age = [person valueForKey:@"age"];
NSLog(@"person = %@, name = %@, age = %@",person, name,age);
//Runtime访问私有属性
unsigned int count = 0;
Ivar *member = class_copyIvarList([person class], &count);
for (int i = 0; i < count; i++) {
Ivar ivar = member[i];
const char *memberName = ivar_getName(ivar);
NSLog(@"memberName = %s",memberName);
Ivar nameN = member[0];
//修改属性值
object_setIvar(person,nameN , @"Mao");
//NSLog(@"nameN = %s",nameN);
}
}
return 0;
}
打印结果
2016-04-22 11:30:31.658 Runtime[7715:476346] person = <Person: 0x100206d90>, name = m, age = 18
2016-04-22 11:30:31.659 Runtime[7715:476346] memberName = _name
2016-04-22 11:30:31.659 Runtime[7715:476346] memberName = _age
2016-04-22 11:30:31.659 Runtime[7715:476346] memberName = _height
2016-04-22 11:30:31.660 Runtime[7715:476346] memberName = _sex
**Program ended with exit code: 0**
- 3.iOS Extension 是什么?能列举几个常用的 Extension 么?
Extension是 iOS 8的重大更新
今日插件(Today widget)
分享(Share)
操作(Action)
图片编辑(Photo Editing)
文档管理(Document Provider)
自定义键盘(Custom keyboard)
4 如何把一个包含自定义对象的数组序列化到磁盘?
优先个步骤是让你的Person类NSCoding协议。其基本策略是序列化和非序列化每个想要会话之间持久化对象的实例变量。5.什么是响应链,它是怎么工作的?
UIResponse对象拥有一个nextResponder指针的时候相关的对象可以通过该指针组成一个响应对象链,当触摸View,通过这个指针指向UIViewController -->UIWindow-->UIApplication,(通过nextResponder指针)
//响应对象链
//
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
//触摸次数
if (touch.tapCount == 1) {
[[self nextResponder] touchesBegan:touches withEvent:event];
return;
}
MMHLogFunc;
}
- 6.为什么用队列管理事件,而不用栈?
队列先进先出,能保证先产生的事件先处理。栈先进后出。
7.线程同步(线程加锁),线程安全问题
Synchronize(self){ 需要加锁的代码 }
优点:防止多条线程抢夺同一块资源
缺点:消耗CPU资源
买票问题
//三条线程同时卖票
NSThread thread01 = [[NSThread alloc] init];
NSThread thread02 = [[NSThread alloc] init];
NSThread thread03 = [[NSThread alloc] init];
//启动线程
[thread01 start];
[thread02 start];
[thread03 start];
//线程就绪
//线程Running运行
//线程阻塞(sleep)
NSInteger count = 100;//100张票
While(1)
{
synchronize(self){
//卖票代码
}
}
8.原子性与非原子性属性
atomic:线程安全的(自动加锁,消耗大量CPU,set和get方法自动加锁,但是平凡调用)
noatomic:非线程安全的
避免抢夺同一块资源,在服务器端处理
线程间的通信
举例下载和传输方法在子线程中执行,执行完毕 后再主线程调用
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// 在子线程中调用download方法下载图片
[self performSelectorInBackground:@selector(download) withObject:nil];
}
-(void)download
{
//1.根据URL下载图片
//从网络中下载图片
NSURL *urlstr=[NSURL URLWithString:@"fdsf"];
//把图片转换为二进制的数据
NSData *data=[NSData dataWithContentsOfURL:urlstr];//这一行操作会比较耗时
//把数据转换成图片
UIImage *image=[UIImage imageWithData:data];
//2.回到主线程中设置图片
[self performSelectorOnMainThread:@selector(settingImage:) withObject:image waitUntilDone:NO];
}
//设置显示图片
-(void)settingImage:(UIImage *)image
{
self.iconView.image=image;
}
GCD常用函数
dispatch_barrier_async(queue , ^{
)
//barrier的作用是,先执行它前面的,执行完之后再执行后面的
- 延迟执行方法(NSTimer,performSlector ... afterDealy)
- 一次性执行
dispatch_once
在程序运行中只被执行一次。防止多次加载资源 - 快速迭代,
dispatch_apply
比for循环高效,比如:剪切文件到某个文件夹中。for循环是一次一次执行,快速迭代几乎同时执行。
RunLoop
提高CPU性能,循环处理各种消息事件。