最近又要把所有的概念性东西刷一遍, 大家应该知道下一步要干啥了,持续更新中。。。
1、KVO实现原理
KVO是基于runtime机制实现的,当一个对象属性被观察时, 系统会动态的创建一个派生类, 并重写被观察属性的setter方法。
每个类对象中都有一个isa指针指向当前类,当一个类对象的第一次被观察,那么系统会偷偷将isa指针指向动态生成的派生类,从而在给被监控属性赋值时执行的是派生类的setter方法, 重写的 setter 方法会负责在调用原 setter 方法之前和之后,通过willChangeValueForKey: 和 didChangevlueForKey:方法,调用observeValueForKey:ofObject:change:context:方法, 通知所有观察者值的改变。
2、define 和 const常量
- define在预处理阶段进行替换,const常量在编译阶段使用
- 宏不做类型检查,仅仅进行替换,const常量有数据类型,会执行类型检查
- define不能调试,const常量可以调试
- define定义的常量在替换后运行过程中会不断地占用内存,而const定义的常量只分配一次内存,效率更高
- define可以定义一些简单的函数,const不可以
理解的文章有:
15分钟弄懂 const 和 #define
iOS 宏(define)与常量(const)的正确使用
1.const NSString *HSCoder = @"汉斯哈哈哈";
2.NSString const *HSCoder = @"汉斯哈哈哈";
3.NSString * const HSCoder = @"汉斯哈哈哈";
1.const NSString *HSCoder = @"汉斯哈哈哈";
"*HSCoder"不能被修改, "HSCoder"能被修改
2.NSString const *HSCoder = @"汉斯哈哈哈";
"*HSCoder"不能被修改, "HSCoder"能被修改
3.NSString * const HSCoder = @"汉斯哈哈哈";
"HSCoder"不能被修改,"*HSCoder"能被修改
注意:1和2其实没什么区别
#5 结论:const右边的总不能被修改
3、static关键字的作用
- 修饰局部变量
让局部变量只初始化一次
局部变量在程序中只有一份内存
对局部变量用static声明,把它分配在静态存储区,该变量在整个程序执行期间不释放,其所分配的空间始终存在
并不会改变局部变量的作用域,仅仅是改变了局部变量的生命周期(只到程序结束,这个局部变量才会销毁)
函数中的局部变量的值在函数调用结束后不消失而继续保留原值,即其占用的存储单元不释放,在下一次再调用的时候该变量已经有值。
- 修饰全局变量
默认情况下的全局变量 作用域是整个程序(可以通过extern来引用) 被static修饰后仅限于当前文件来引用 ,其他文件不能通过extern来引用
开发中static与const的联合使用 定义一个只能在当前文件访问的全局常量:
static NSString*yourName =@"Lucy";
4、
5、 如何高性能的给 UIImageView 加个圆角?
-
错误的解决方案
使用下面的方式会强制Core Animation提前渲染屏幕的离屏绘制, 而离屏绘制就会给性能带来负面影响,会有卡顿的现象出现self.view.layer.cornerRadius = 5; self.view.layer.masksToBounds = YES;
方法一
- (UIImage *)circleImage
{
// NO代表透明,申请画布
UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0);
// 获得上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 添加一个圆
CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
CGContextAddEllipseInRect(ctx, rect);
// 裁剪
CGContextClip(ctx);
// 将图片画上去
[self drawInRect:rect];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
// 关闭上下文
UIGraphicsEndImageContext();
return image;
}
-
方法二
- (UIImage*)drawImageWithSize:(CGSize)size imageName:(NSString *)imageName { // 申请一块特定大小的画布 // UIGraphicsBeginImageContext(size); UIGraphicsBeginImageContextWithOptions(size, NO, 1.0); // 画出一个与画布等大的圆,圆以外的部分设置为无效区 [[UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, size.width, size.height)] addClip]; UIImage *oldImage = [UIImage imageNamed:imageName]; [oldImage drawInRect:CGRectMake(0, 0, size.width, size.height)]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; }
6、Runtime
- 消息机制方法调用流程