#pragma mark - 单例方法(完整的方法)
系统的单例方法名称 sharedApplication defaultManager standardUserDefaults currentDevice

[UIApplication sharedApplication];

[NSFileManager defaultManager];

[NSUserDefaults standardUserDefaults];

[UIDevice currentDevice];
+ (instancetype)sharedInstace;

// 用来保存唯一的单例对象
static id _instace; + (id)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [super allocWithZone:zone];
});
return _instace;
} + (instancetype)sharedInstace
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [[self alloc] init];
});
return _instace;
} - (id)copyWithZone:(NSZone *)zone
{
return _instace;
} - (id)retain { return self; }
- (oneway void)release { }
- (id)autorelease { return self;}
- (NSUInteger)retainCount { return ;}

#pragma mark--蒙板(遮罩层)

//1、添加蒙板(遮罩)
UIButton * coverButton = [[UIButton alloc] initWithFrame:self.view.bounds];

coverButton.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.5];

[coverButton addTarget:self action:@selector(tapcoverButton:) forControlEvents:UIControlEventTouchUpInside];

coverButton.alpha = 0.0;

[self.view addSubview:coverButton];

//2、将需要放大的图像按钮弄到最前面
//bringSubviewToFront
[self.view bringSubviewToFront:self.iconButton];

//3、动画放大图像按钮
CGFloat width = self.view.bounds.size.width;

CGFloat height = width;

CGFloat y = (self.view.bounds.size.height - height) * 0.5;

[UIView animateWithDuration:1.0 animations:^{

self.iconButton.frame = CGRectMake(0, y, width, height);

coverButton.alpha = 1.0;
}];

[UIView animateWithDuration:1.0 animations:^{

//将图像恢复初始位置
self.iconButton.frame = CGRectMake(112, 125, 150, 150);

button.alpha = 0.0;
} completion:^(BOOL finished) {

//动画完成之后,删除cover
[button removeFromSuperview];
}]; 

#pragma mark -- 判断一个路径里面的文件总大小(NSString的分类)

- (NSInteger)fileSize
{
NSFileManager *mgr = [NSFileManager defaultManager]; // 判断是否为文件夹
BOOL dir = NO;
BOOL exists = [mgr fileExistsAtPath:self isDirectory:&dir]; // 文件\文件夹不存在
if (exists == NO) return ; if (dir) { // self是一个文件夹
// 遍历caches里面的所有内容 --- 直接和间接内容
NSArray *subpaths = [mgr subpathsAtPath:self];
NSInteger totalByteSize = ; for (NSString *subpath in subpaths) {
// 获得全路径
NSString *fullSubpath = [self stringByAppendingPathComponent:subpath]; // 判断是否为文件夹 subpath为系统返回的路径,肯定存在文件夹或者文件
BOOL dir = NO;
[mgr fileExistsAtPath:fullSubpath isDirectory:&dir]; if (dir == NO) { // 不是文件夹,是文件
totalByteSize += [[mgr attributesOfItemAtPath:fullSubpath error:nil][NSFileSize] integerValue];
}
}
return totalByteSize;
} else { // self是一个文件
return [[mgr attributesOfItemAtPath:self error:nil][NSFileSize] integerValue];
}
}

#pragma mark - 自己封装刷新控件

KVO 监听父视图的contentOffset
scrollView.addObserver(self, forKeyPath: "contentOffset", options: [], context: nil)

// 本视图从父视图上移除
// 提示:所有的下拉刷新框架都是监听父视图的 contentOffset
// 所有的框架的 KVO 监听实现思路都是这个!
override func removeFromSuperview() {
// superView 还存在
superview?.removeObserver(self, forKeyPath: "contentOffset")

super.removeFromSuperview() //在这句话之前移除监听

// superView 不存在
}

// 观察者模式,在不需要的时候,都需要释放
// - 通知中心:如果不释放,什么也不会发生,但是会有内存泄漏,会有多次注册的可能!
// - KVO:如果不释放,会崩溃!

#pragma mark - KVO底层实现原理

// 利用KVO可以很简单的实现监听对象的属性发生改变,KVO的底层: "重写setter方法"

// 结论:只有触发了setter方法才会触发KVO的监听

// 底层实现如下:

// 1.动态创建NSKVONotifying_Person,NSKVONotifying_Person是Person子类,利用NSKVONotifying_Person做KVO的实现
// 2.修改当前对象的isa指针->NSKVONotifying_Person
// 3.只要调用对象的set,就会调用NSKVONotifying_Person的setter方法
// 4.重写NSKVONotifying_Person的setter方法
//    4.1 [super set:]
//    4.2 通知观察者,告诉你属性改变

连接--> KVO底层实现原理,仿写KVO

#pragma mark - 头文件标志的含义

C : 类NSString
f : NSObjCRuntime
T : 基本数据类型NSInteger/结构体 NSRange
V : 字符串常量
k : 枚举

更多内容--> 博客导航 每周一篇哟!!!

有任何关于iOS开发的问题!欢迎下方留言!!!或者邮件lieryangios@126.com 虽然我不一定能够解答出来,但是我会请教iOS开发高手!!!解答您的问题!!!

Object-C知识点 (三) 单例 蒙版 刷新 KVO底层的更多相关文章

  1. js(三) ajax异步局部刷新技术底层代码实现

    ajax 异步 javaScript and xml 开发五步骤: 1. 创建对象 XMLHttpRequest(chrome,firefox) ie... jquery 2. 找到连接, http的 ...

  2. 设计模式(三)Singleton Pattern单例设计模式

    1.饿汉式 public class SingletonDemo { private static SingletonDemo s=new SingletonDemo(); private Singl ...

  3. Kotlin入门(18)利用单例对象获取时间

    前面介绍了,使用扩展函数可以很方便地扩充数组Array的处理功能,例如交换两个数组元素.求数组的最大元素等等.那么除了数组之外,日期和时间的相关操作,也是很常见的,比如获取当前日期,获取当前时间.获取 ...

  4. iOS 设计模式之单例

    设计模式:单例 一.  单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并 ...

  5. Spring IOC 容器源码分析 - 获取单例 bean

    1. 简介 为了写 Spring IOC 容器源码分析系列的文章,我特地写了一篇 Spring IOC 容器的导读文章.在导读一文中,我介绍了 Spring 的一些特性以及阅读 Spring 源码的一 ...

  6. 探索Scala(3)-- 单例对象

    研究一下Scala语言的单例对象(Singleton Objects),为下一篇文章做准备. static不是keyword 上一篇文章提到过,interface并非Scala语言keyword,能够 ...

  7. Java设计模式:Singleton(单例)模式

    概念定义 Singleton(单例)模式是指在程序运行期间, 某些类只实例化一次,创建一个全局唯一对象.因此,单例类只能有一个实例,且必须自己创建自己的这个唯一实例,并对外提供访问该实例的方式. 单例 ...

  8. Spring IOC(三)单例 bean 的注册管理

    Spring IOC(三)单例 bean 的注册管理 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) 在 Spring 中 ...

  9. oop的三种设计模式(单例、工厂、策略)

    参考网站 单例模式: 废话不多说,我们直接上代码: <?php /** 三私一公 *私有的静态属性:保存类的单例 *私有的__construct():阻止在类的外部实例化 *私有的__clone ...

随机推荐

  1. angular.js实现省市区三级联动指令

    不多说,直接上代码,一开始搞了好久,最后才弄懂,希望对大家有帮助 1.jade div.col-md-2 select.form-control(ng-options="value.code ...

  2. WinForm笔记

    Hi All, 分享一个学WinForm时的笔记: 1. 关键字 partial:是部分类,允许将一个类放在多个文件当中. 2. MessageBox()类相当于Console.WriteLine() ...

  3. 开源网络操作系统--VyOS

    User Guide Jump to: navigation, search Contents 1 Introduction 2 Installation 3 Using the Command-Li ...

  4. 编写原生的Node.js模块

    导语:当Javascript的性能遭遇瓶颈,或者需要增强Javascript能力的时候,就需要依赖native模块来实现了. 应用场景 日常工作中,我们经常需要将原生的Node.js模块做为依赖并在项 ...

  5. 查看c语言的函数运行时间的简单模板

    /* clock():捕捉从程序开始运行到 clock() 被调用时所耗费的时间,时间单位 是clock tick, 即:"时钟打点". 常数CLK_TCK:机器时钟每秒所走的时钟 ...

  6. sql定时自动备份(定时作业)

    第一步: 右键启动"SQL Server 代理"

  7. 一天搞定CSS:BFC布局与普通文档流布局比较--15

    BFC:Block Formatting Contexts–块级元素格式化上下文 1.BFC定义 它决定了块级元素如何对它的内容进行布局,以及与其它元素的关系和相互作用 关键词解释: 块级元素:父级( ...

  8. js 次方 开方

    次方 ,用Math.pow(值,次方数) 如: Math.pow(3,2);   3的平方 Math.Pow(2,3);   2的立方 开方Math.sqrt(值) 如: Math.sqrt(9);  ...

  9. 基于java.util.logging实现轻量级日志记录库(增加根据当前类class初始化,修复线程池模型(javaEE)下的堆栈轨迹顺序与当前调用方法不一致问题)

    前言: 本章介绍自己写的基于java.util.logging的轻量级日志记录库(baseLog). 该版本的日志记录库犹如其名,baseLog,是个实现日志记录基本功能的小库,适合小型项目使用,方便 ...

  10. SQL Server使用导入导出向导导入超过4000个字符的字段的数据

    在使用SQL Server导入导出向导导入数据的时候,我们经常会碰到某个单元格的数据超长而被截断报错的情况.本文针对这种场景给出相应的解决方案.   环境描述:SQL Server 2012,文件源: ...