#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. linux系统管理--进程管理

    这两天一直维护公司的服务器,主要对进程管理和linux工作管理,把一些零散的知识整理一下,书归正传~ 什么进程?  以下是百度给的解释的进程,说实话,云里雾里的,其实linux进程和windows进程 ...

  2. Spring切面编程步骤

    什么是面向切面编程 面向对象的编程主要注重核心业务,而面向切面编程主要关注一些不是核心的业务,但又是必须的辅助功能,比如一个完整的系统中,记录平时系统运行时抛出的异常,需要我们去记录,以便我们对系统尽 ...

  3. Android 内存泄漏分析与解决方法

    在分析Android内存泄漏之前,先了解一下JAVA的一些知识 1. JAVA中的对象的创建 使用new指令生成对象时,堆内存将会为此开辟一份空间存放该对象 垃圾回收器回收非存活的对象,并释放对应的内 ...

  4. awk之随机函数rand()和srand() (转)

    转自:http://blog.chinaunix.net/uid-10540984-id-2942041.html 文件: 1234567 abcdefg ......   现在想要随机抽取5列组成下 ...

  5. javascript获取json对象的key名称的两种方法

    javascript获取json对象的key名称的两种方法 数据处理中,你可能接收到一个不确定内容格式的json对象,然后要把key的值提取出来.今天试过两种可以提取json key的方法,均可以正常 ...

  6. poj3683

    poj3683 题意 n对新人举行婚礼,婚礼在不同时间段但可能重叠,婚礼有开始(Si).结束(Ti).仪式举行时间(Di),问能否给出一种举行方案,使得神父能参加所有的婚礼并举行仪式. 分析 xi为真 ...

  7. 网络编程3之TCP/IP协议

    在TCP/IP协议中,最重要的协议是[TCP.UDP.IP]协议 1.TCP/IP协议特点 1)Internet上不同系统之间互联的一组协议 2)为分散和不同类型的硬件提供通用的编程接口. 3)TCP ...

  8. Java常用类之String类练习

    1.编程. 已知字符串:"this is a test of java". 按要求执行以下操作: (1) 统计该字符串中字母s出现的次数 (2) 取出子字符串"test& ...

  9. [原创]使用logcat快速抓取android崩溃日志

    在android APP测试过程中会发生不少的crash,目前抓取日志的主流方法是通过eclipse或者eclipse的ddms组件进行捕抓,这两种方法有个缺点是启动时非常耗时.本文通过adb程序与b ...

  10. 解析PHP面向对象的三大特征

    class BenHang extends Card{ /*构造函数与及构造的继承*/ function __construct($cardno,$pwd, $name,$money){ parent ...