//runloop讲解
//1.
什么是
runloop?
//runloop
运行循环
,
循环处理线程中的任务
,
负责任务中的调度和执行
//2.
每个线程中
,
无论是主线程还是子线程
,
系统都默认帮我们创建了
runloop,
主线程中的
runloop
是默认打开的
,
而子线程中的
runloop
是默认关闭的
//runtime讲解
//1. runtime是什么?
//1.1 runtime是一套比较底层的纯C语言的API, runtime就是一个库, 一个C语言库, 包含了许多底层操作的C语言API。
//1.2平时我们编写的OC代码, 在程序运行期间, 其实最终都经过runtime转成了C语言代码, runtime是OC幕后工作者, 是整个OC的底层。
//1.3举例:
//Student *stu = [[Student alloc] init];经过runtime被编译成objc_msgSend(objc_msgSend("Student", "alloc"), "init");
//objc_msgSend其实就是向某个对象发送什么消息
//2.怎么使用runtime?
//2.1 runtime属于OC底层, 可以进行非常底层的操作
eg.
//*在程序中运行过程中,动态创建一个类, (KVO)
//*向类中动态添加方法, 添加属性
//
// AppDelegate.m
// Runtime
自动归档
//
//
//
//
// Created by
CONGAING
on 15/7/13.
// Copyright (c) Congwang
. All rights reserved.
//
#import "AppDelegate.h"
#import "Student.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- ( BOOL )application:( UIApplication *)application didFinishLaunchingWithOp tions:(
NSDictionary
*)launchOptions {
self
.
window
= [[
UIWindow
alloc
]
initWithFrame
:[[
UIScreen
mainScreen
]
bounds
]];
// Override point for customization after application launch.
self
.
window
.
backgroundColor
= [
UIColor
whiteColor
];
[
self
.
window
makeKeyAndVisible
];
// runtime:
运行时机制
// 1.
是什么?
// 1.1runtime
是一套比较底层的纯
C
语言的
API
,
runtime
就是一个库,一个
C
语言库,包含了许多底层的
C
语言
API
// 1.2
平时我们编写的
OC
代码,在程序运行过程中,其实最终都是转成了
runtime
的
C
语言代码,
runtime
算是
OC
的幕后工作者,是整个
OC
的底层
// 1.3
举个例子
// oc
中的代码:
[Student alloc] init]
经过
runtime
后,其实最终在底层生成
C
语言代码:
// objc_msgSend(objc_msgSend("Student","alloc"), "init")
// objc_msgSend
其实就是想某个对象发送什么消息,这个函数第一个参数是类型或对象名,第二个参数是消息的名字,这些代码比较底层
// 2.
用过吗?怎么用?
// 2.1 runtime
是属于
OC
的底层,可以进行一些非常底层的操作(用
OC
无法实现的,或者说不好实现)
eg
// *
在程序运行过程中,动态创建一个类,(比如
KVO
和
KVC
的底层实现)
// *
在程序运行过程中,动态为某个类添加属性/方法,修改属性值,修改方法
// *
遍历一个类中所有的属性和实例变量和所有方法
// 3.
// 3.1
相关的头文件
// #import
// #import //
消息发送机制,可以直接用底层函数,进行消息发送
// 3.2
相关应用
// *NSCoding
(归档和解挡)
// *
字典转模型(利用
runtime
遍历模型对象的所有属性,根据属性名从字典中取出对应的值,设置到模型的属性上)
// *kvo
(利用
runtime
动态产生一个类)
// 3.3
相关函数
// msg_send:
给对象发送消息,来自
// class_copyMethodList,
遍历某个类中所有的方法,来自
// class_copyIvarList,
遍历某个类中所有的实例变量的方法,来自
//
运行时必备常识:
// 1.Ivar
:成员变量的意思
// 2.Method
:成员方法的意思
// 3.property:
属性
//
下面我们开始实现动态归档
//
打开
student.m,
引入
Student
*student = [[
Student
alloc
]
init
];
student.
name1
=
@"sunlin"
;
student.
age
=
18
;
student.
name2
=
@"sunlin"
;
student.
name3
=
@"sunlin"
;
student.
name4
=
@"sunlin"
;
student.
name5
=
@"sunlin"
;
student.
name6
=
@"sunlin"
;
student.
name7
=
@"sunlin"
;
//
归档文件的路径
NSString
*filePath = [
NSHomeDirectory
()
stringByAppendingPathCom ponent
:
@"person.archiver"
];
//
判断该文件是否存在
if
(![[
NSFileManager
defaultManager
]
fileExistsAtPath
:filePath]) {
//
不存在的时候,归档存储一个
Student
的对象
NSMutableData
*data = [
NSMutableData
data
];
NSKeyedArchiver
*archiver = [[
NSKeyedArchiver
alloc
]
initForWritingWithMutabl eData
:data];
[archiver
encodeObject
:student
forKey
:
@"student"
];
[archiver
finishEncoding
];
BOOL
success = [data
writeToFile
:filePath
atomically
:
YES
];
if
(success) {
NSLog
(
@"
归档成功!
"
);
}
}
else
{
//
存在的时候,不再进行归档,而是解挡!
NSData
*data = [
NSData
dataWithContentsOfFile
:filePath];
NSKeyedUnarchiver
*unArchiver = [[
NSKeyedUnarchiver
alloc
]
initForReadingWithData
:data];
Student
*studentFromSaving = [unArchiver
decodeObjectForKey
:
@"student"
];
NSLog
(
@"%@, %lu"
, studentFromSaving.
name7
, studentFromSaving.
age
);
}
#import "AppDelegate.h"
#import "Student.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- ( BOOL )application:( UIApplication *)application didFinishLaunchingWithOp
}
@end
//
// Student.h
// Runtime自动归档
//
//
//
// Created by王聪
on 14/7/13.
// Copyright (c) 2015
年congWang
. All rights reserved.
//
#import
#import
@interface Student : NSObject<</span>NSCoding>
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, copy) NSString *name1;
@property (nonatomic, copy) NSString *name2;
@property (nonatomic, copy) NSString *name3;
@property (nonatomic, copy) NSString *name4;
@property (nonatomic, copy) NSString *name5;
@property (nonatomic, copy) NSString *name6;
@property (nonatomic, copy) NSString *name7;
@end
#import
#import
@interface Student : NSObject<</span>NSCoding>
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, copy) NSString *name1;
@property (nonatomic, copy) NSString *name2;
@property (nonatomic, copy) NSString *name3;
@property (nonatomic, copy) NSString *name4;
@property (nonatomic, copy) NSString *name5;
@property (nonatomic, copy) NSString *name6;
@property (nonatomic, copy) NSString *name7;
@end
//
// Student.m
// Runtime自动归档
//
//
//
// Created by
王聪 on 15/7/13.
// Copyright (c) 2015
年
王聪. All rights reserved.
//
#import "Student.h"
@implementation Student
- (void)encodeWithCoder:(NSCoder *)encoder
{
unsigned int count = 0;
// 利用runtime获取实例变量的列表
Ivar *ivars = class_copyIvarList([self class], &count);
for (int i = 0; i < count; i ++) {
// 取出i位置对应的实例变量
Ivar ivar = ivars[i];
// 查看实例变量的名字
const char *name = ivar_getName(ivar);
// C语言字符串转化为NSString
NSString *nameStr = [NSString stringWithCString:nameencoding:NSUTF8StringEncoding];
// 利用KVC取出属性对应的值
id value = [self valueForKey:nameStr];
// 归档
[encoder encodeObject:value forKey:nameStr];
}
// 记住C语言中copy出来的要进行释放
free(ivars);
}
- (id)initWithCoder:(NSCoder *)decoder
{
if (self = [super init]) {
unsigned int count = 0;
Ivar *ivars = class_copyIvarList([self class], &count);
for (int i = 0; i < count; i ++) {
Ivar ivar = ivars[i];
const char *name = ivar_getName(ivar);
//
NSString *key = [NSString stringWithCString:nameencoding:NSUTF8StringEncoding];
id value = [decoder decodeObjectForKey:key];
// 设置到成员变量身上
[self setValue:value forKey:key];
}
free(ivars);
}
return self;
}
@end
#import "Student.h"
@implementation Student
- (void)encodeWithCoder:(NSCoder *)encoder
{
}
- (id)initWithCoder:(NSCoder *)decoder
{
}
@end