MVC,MVVM
M<--->C<--->V
M<--->VM<--->V
VM负责的部分 将 model里属性值 部分,处理成view显示的部分,同时兼顾从网络,资源库等地方获取数据,view部分不直接和model产生关系,自负责利用viewmodel 暴露的方式,接口来获取显示的内容
KVO
原理 重写子类set方法
在valueWillChange和valueDidChange之间,调用父类set方法改变属性值,然后通过obver....回调方法通知监听者被监听的属性发生改变
在NSOperation 中修改isFinish 来手动调用kvo的valueWillChange和valueDidChange来实现对队列任务的控制 详解
自定义 kvo
自定义通知
Runtime
swizzle 原理
每一个方法 Method 是结构体包含着 sel(方法编号选择器) IMP 方法指针
通过sel找到对应的imp 通过imp去调用具体的方法
swizzle 是将sel对应的imp进行交换, 假设系统中是selector1 对应 imp1 我们自定义的是selector2 对用的 imp2 通过method_exchangeImplemetation(Method m1,Method m2)将 selector1 指向imp2 selector2指向imp1
添加方法
class_addMethod(class, origSelector,method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
此方法要写在+load里 原因,+load方法是在类加载时候调用,执行较早,系统调用,唯一性,不用担心资源抢夺问题
调动未实现的方法会发生crash,补救措施(objc_msgForward,是用于消息转发的:当向一个对象发送一条消息,但它并没有实现的的候,_objc_msgForward会尝试做消息转发。)
1 首先会调用 +(BOOL)resolveInstanceMethod 或者+(BOOL)resolveClassMethod 方法 允许动态添加未实现的方法,进行补救.只要没有通过class_addMethod添加对应的方法,就会进行下一步,eg:
+(BOOL)resolveInstanceMethod:(SEL)sel{
BOOL isFinish = [super resolveInstanceMethod:sel];
if (sel == NSSelectorFromString(@"testsss")) {
class_addMethod([self class], sel, (IMP)sss, "v@:");
isFinish = YES;
}
return isFinish;
}
2 调用-(id)forwardingTagetForselector ,尝试找到一个能响应该消息的对象。如果获取到,直接返回该对象 eg:
-(id)forwardingTargetForSelector:(SEL)aSelector{
if(aSelector == NSSelectorFromString(@"test"))
Class class = NSClassFromString(@"Test");
return class;
}
return nil;
}
3 调用methodSigntureForSelector 尝试获得一个方法签名。如果获取不到,则直接调用doesNotRecognizeSelector抛出异常。如果能获取,则返回该方法签名 eg:
if (aSelector == NSSelectorFromString(@"test")) {
Class class = NSClassFromString(@"Test");
return [NSMethodSignature signatureWithObjCTypes:method_getTypeEncoding(class_getInstanceMethod(class, aSelector))];
}
4 调用forwardInvocation:方法 利用第三步返回的方法签名,通过NSInvocation 实现对应的方法 eg:
-(void)forwardInvocation:(NSInvocation *)anInvocation{
Class class = NSClassFromString(@"Test");
[anInvocation invokeWithTarget:[[class alloc] init]];
}
GCD
线程之间的通信
[self performSelectorOnMainThread:@selector(dothing:) withObject:@[@"1"] waitUntilDone:YES];
[self performSelector:@selector(dothing:) onThread:thread withObject:nil waitUntilDone:YES];
同步任务: 优先级高,在线程中有执行顺序,不会开启新的线程
异步任务: 优先级低,在线程中执行没有顺序,看cpu闲不闲。在主队列中不会开启新的线程,其他队列会开启新的线程,(串行开启一条线程,并行开启多条线程)
队列分为 [串行队列] 和 [并行队列] :
串行队列:队列中的线程按顺序执行(不会同时执行)
并行队列:队列中的线程会并发执行(同时执行
串行与并行针对的是队列,而同步与异步,针对的则是线程
多个请求完成后统一刷新页面 ,思路:利用group,创建任务组
通过 dispach_group_enter,通知任务进入group中,通过dispach_group_leave 通知任务完成离开group,最后通过dispach_group_notify来通知主线程刷新页面,eg:
NSURLSession *session = [NSURLSession sharedSession];
dispatch_group_t dispatchGroup = dispatch_group_create();
dispatch_group_enter(dispatchGroup);
NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL URLWithString:@"https://www.baidu.com"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"任务1完成");
dispatch_group_leave(dispatchGroup);
}];
[task resume];
dispatch_group_enter(dispatchGroup);
NSURLSessionDataTask *task2 = [session dataTaskWithURL:[NSURL URLWithString:@"https://www.baidu.com"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"任务2完成");
dispatch_group_leave(dispatchGroup);
}];
[task2 resume];
dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){
NSLog(@"end");
});
}
dispatch_group_t group = dispatch_group_create();
NSMutableArray *arr = [NSMutableArray array];
dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
for (NSInteger i = 0; i<20; i++) {
dispatch_group_async(group, queue, ^(){
dispatch_group_enter(group);
NSLog(@"请求%zd",i);
sleep(3);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[arr addObject:@(i)];
dispatch_group_leave(group);
});
});
}
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"%zd",arr.count);
});
内存管理
SQL
网络层通讯
4层网络结构
应用层(http) 传输层(TCP,UDP) 网络层(IP协议) 数据链路层(网络传输,路由中转)
tcp/udp区别
tcp建立连接3次握手,断开连接4次握手,安全稳定不会丢包,适合数据量大的情况,速度较慢
udp不需要建立连接直接传输,速度快,但不稳定,容易发生丢包的问题
http/https区别
Cocoapods
install和update 区别
需要增加或移除某一个或多个pods时,需要使用pod install
1.每一次执行pod install命令-下载安装新的pods-每一个pod的版本都会被记录在Podfile.lock文件中。这个文件追踪每个pod的安装版本并且将它锁定
2.使用pod install时,它只是解决了之前未列入Podfile.lock的文件中的pods的依赖关系。
对于那些已经出现在Podfile.lock文件中的pods,它只会下载该文件中指定版本的pod,并不会去检索是否存在新的版本
对于Podfile.lock文件中还没有锁住版本的新增pod,它会按照Podfile文件中描述的方式去搜索匹配的版本
需要更新这个pods的版本时,需要使用pod update
CocoaPods会去找到指定PODNAME的更新,不再从Podfile.lock列表中的版本作比对,它会尽可能的更新到最新版本(前提是新版本和你在Podfile中所设的约束匹配)。
在测试的时候引入这个框架,而release不引入,podfile文件中需要怎么写呢?
pod 'afnxxx', :configurations => ['Debug']
git命令
git命令
rebase作用,合并解决冲突
rebase和merge区别
网友评论