开发一:
1.内存的 stack and heap: [https://www.cnblogs.com/yanghong-hnu/p/4705755.html]
一: APP系统自动分配 :
1).栈区(stack) :存放函数参数/局部变量 (高地址向下分配)
2).堆区(heap) :由程序员释放,否则会导致内存泄漏 (某个位置向上分配)
3).BSS段: 存储未初始化的全局变量和静态变量 Block Started by Symbol
4).数据段(常量区): 存储已经初始化的全局变量/静态变量/常量
5).代码段(Text segment/Code segment): 程序执行代码的一块内存区域,或者一下只读的常量/字符串
二:扩展
1). 栈区 是函数运行时的内存,栈区的 变量 由编译器 负责分配和释放 (栈区有很多个栈)
2). 栈: 是 由低地址向高地址扩展的数据结构,是一块连续的内存块,栈的大小一般是 2M或者1M(编译的时候就已经确定的一个常数)
3). 堆: 是 由高地址向低地址扩展的数据解决,不连续
-
组件化解耦
3.runtime 通过selector 找到IMP
苹果官方的文档: https://opensource.apple.com/source/objc4/
元类/类对象/对象: http://www.jianshu.com/p/64077d59911b
https://juejin.im/entry/587d887f1b69e60058486a71
runtime参考: http://yulingtianxia.com/blog/2014/11/05/objective-c-runtime/
一:runtime 基础
1).发送消息 [receiver message] => objc_msgSend(receiver,selector,arg1,arg2 ....) selector:类型是SEL,相当于方法的ID
2).编译的时候确定了 发送这条消息,但是 receiver 接受这条消息是在 运行时但是class 方法 只能在NSObject中实现了objc_msgSend(objc_super->receiver, @selector(class))
二: selector 和 IMP SEL: 就是方法的签名
SEL selA = @selector(setString:); SEL selB = sel_registerName("setString:"); IMP: typedef id (*IMP)(id, SEL, ...);
就是一个 函数的指针 ,方法的入口Method: (方法名,返回类型,方法的实现),其实这也就实现了OC的动态性,把IMP的实现放在运行中检查struct objc_method { SEL method_name; char *method_types; IMP method_imp;};
三: self 和 super
1、self调用自己方法,super调用父类方法
2、self是类,super是预编译指令struct objc_super { id receiver; Class class; }当使用self 调用的时候,会触发 objc_msgSend(receiver,selector,arg1,arg2 ....)当掉用 [self setName:] 的时候,
会变成 objc_msgSend(self,@select(setName:),arg1)这个selector 就是从self 的isa 指向的类中去查找,找到了 就去指向Method 的IMP 函数指针当编译器遇到[super setName:]时候首先构建objc_super结构体,会调用 objc_msgSendSuper(self->isa,@select(setName:),arg1) 在当前的父亲类中找@selector,找到了就再次调用 objc_msgSend(objc_super->receiver,@select(setName:),arg1),这个时候其实还是self就相当于self 调用父类的方法四:
消息转发+/- resolveInstanceMethod: 当前类自己处理,自己添加方法- forwardingTargetForSelector: 转发给另外一个对象- forwardInvocation: //将整个消息封装成消息传递出去
SEL -> NSMethodSignature->NSInvocation(把方法调用封装成一个对象) -> 设置target/参数/返回值
4.NSProxy
定义一个WeakProxy:
保留一个target 对象- (void)forwardInvocation:(NSInvocation *)invocation // 就是invocation 重新设置target 和 selector在调用之前首先需要
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel 方法签名,因为invocation 需要用到MethodSignature初始化
@interface WeakProxy()
@property (nonatomic,weak) id target;
@end
@implementation WeakProxy
- (instancetype)initWithTarget:(id)target {
self.target = target;
return self;
}
+ (instancetype)weakProxyWithTarget:(id)target {
return [[self alloc]initWithTarget:target];
}//消息转发出去
- (void)forwardInvocation:(NSInvocation *)invocation {
SEL sel = [invocation selector];
if ([self.target respondsToSelector:sel]) {
[invocation setTarget:self.target];
[invocation invoke];
}
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
//获取方法签名,后面才能创建 invocation
NSMethodSignature * tmpMethodSignature = [self.target methodSignatureForSelector:sel];
return tmpMethodSignature;}
@end
-
- runloop 内部逻辑
苹果官方文档:https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html#//apple_ref/doc/uid/10000057i-CH16-SW3run loop objects to help you configure and manage your thread’s run loopeach thread, including the application’s main thread, has an associated run loop object: 每一个thread 都有一个runloop对象
-
多线程
-
GCD
-
防止反编译app
-
YYAsyncLayer 异步绘制
-
优化
-
KVO的实现
-
initialite:在接受第一条消息之前 load:在一个类对象加载到runtime的时候
-
Aspect
-
bug 回调
-
响应链
-
图片浏览器
-
线程
-
视频压缩
麻省理工学院公开课:算法导论 : http://open.163.com/special/opencourse/algorithms.html
网友评论