#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. 超实用Java快捷键

    超实用Java快捷键 Ctrl+1或F2快速修复 Ctrl+D快捷删除行 Shift+Enter 快速切换到下一行,在本行的任何位置都可 Ctrl+F11快速运行代码 Alt+上下键 快速移动行(可多 ...

  2. wiringPi安装

    wiringPi安装   更新软件,输入以下指令:   sudo apt-get update   sudo apt-get upgrade   通过GIT获得wiringPi的源代码   git c ...

  3. hadoop 2.7.3 集群安装

    三台虚拟机,centos6.5 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 :: loca ...

  4. grunt基础配置

    grunt基础配置 要使用grunt来管理项目,一般需要如下的几个步骤: 安装grunt命令行工具grunt-cli 在项目中安装grunt 安装grunt插件 建立并配置Gruntfile.js 安 ...

  5. js常用的4种截取字符串方法

    平常经常把这几个api的参数记混了,于是打算记录下来,当不确定的时候在拿出来翻翻: 在做项目的时候,经常会需要截取字符串,所以常用的方法有slice().substr().substring().ma ...

  6. #416 Div2 C

    #416 Div2 C 题意 一些人去坐车,它们已经按给定顺序排队,每个人可能去不同的目的地,去同一目的地的人一定要被分成一组(去不同目的地的也可被分到同一组),对分好的每一组所有不同的目的地序号作异 ...

  7. hdu3715

    hdu3715 题意 给出一个递归的伪代码,当 x[a[dep]] + x[b[dep]] != c[dep],就向下递归,给出a,b,c数组的值 问 dep 最大多少.其中 0 <= c[i] ...

  8. HTML----网页基础和基本标签

    网页分类: 1.静态网页:所有内容全写死,都写在源代码中,若修改必须修改源代码,后缀为.html或htm 2.动态网页:内容大部分来自于数据库,可以修改,后缀为.aspx(c#).jsp(java). ...

  9. WPF界面XAML中的if……else……

    xaml本身并不支持if--else--,要用Converter替代if--else--来实现我们想要的效果,知者请速离开,不要浪费时间   需求:按照Window的WindowState来决定Gri ...

  10. bootstrapValidator 使用(包含入门demo,常用方法,以及常用的规则)

    一   什么是bootstrapValidator?    -- 一个基于 jquery,boostrap 的表单验证框架....简单实用上手快,页面美观还过得去,不废话了,直接撸. 二  boots ...