当前位置: 首页 > news >正文

建设房屋出租网站观澜做网站

建设房屋出租网站,观澜做网站,管理网页,中卫网红美食打卡地1 单例模式 1.1 什么是单例 单例模式在整个工程中#xff0c;相当于一个全局变量#xff0c;就是不论在哪里需要用到这个类的实例变量#xff0c;都可以通过单例方法来取得#xff0c;而且一旦你创建了一个单例类#xff0c;不论你在多少个界面中初始化调用了这个单例方…1 单例模式 1.1 什么是单例 单例模式在整个工程中相当于一个全局变量就是不论在哪里需要用到这个类的实例变量都可以通过单例方法来取得而且一旦你创建了一个单例类不论你在多少个界面中初始化调用了这个单例方法取得对象它们所有的对象都是指向的同一块内存的存储空间即单例类保证了该类的实例对象是唯一存在的一个。 1.2 单例模式的优缺点 优点 一个类只被实例化一次提供了对唯一实例的受控访问。节省系统资源。允许可变数目的实例。 缺点 一个类只有一个对象可能造成责任过重在一定程度上违背了“单一职责原则”。由于单例模式中没有抽象层因此单例类的扩展有很大的困难。滥用单例将带来一些负面问题如为了节省资源将数据库连接池对象设计为单例类可能会导致共享连接池对象的程序过多而出现连接池溢出如果实例化的对象长时间不被利用系统会认为是垃圾而被回收这将导致对象状态的丢失。 1.3 单例的实现 单例的实现分为两种懒汉式和饿汉式。 懒汉式顾名思义不到万不得已就不会去实例化类也就是说在第一次用到类实例的时候才会去实例化。饿汉式饿了肯定会饥不择食所以在单例类加载的时候就进行实例化。 特点和选择 由于要进行线程同步所以在访问量比较大或者可能访问的线程比较多时采用饿汉实现可以实现更好的性能这是以空间换时间。在访问量较小时采用懒汉实现这是以时间换空间。 1.3.1 懒汉式 使用synchronized static id manager nil;(instancetype)shareInstance {// 防止多次加锁if (!manager) {synchronized (self) {if (!manager) {manager [[super allocWithZone:NULL] init];}}}return manager; }第一次if(!manager)判断是为了避免在对象创建后多次访问导致的多次加锁浪费性能。第二次if(!manager)判断就是判断此时单例是否存在不存在就重新创建。 使用GCD (instancetype)shareInstance {static dispatch_once_t onceToken;dispatch_once(onceToken, ^{manager [[super allocWithZone:NULL] init];});return manager; }dispatch_once它没有使用重量级的同步机制性能也优于前者并且更加高效。 dispatch_once无论使用多线程还是单线程都只执行一次在安全的前提下也保证了性能。 dispatch_once主要是根据onceToken的值来决定怎么执行代码 当onceToken为0时线程执行dispatch_once的block中的代码。当onceToken为-1时线程跳过dispatch_once的block中的代码。当onceToken为其他值时线程被阻塞等待onceToken值改变。 dispatch_once的执行流程 当线程调用shareInstance此时onceToken为0执行dispatch_once的block中的代码此时onceToken中的值为其他值。这时如果有其他线程再调用shareInstance方法时onceToken值为其他值线程阻塞。当block线程执行完block后onceToken变为-1。其他线程不再阻塞跳过block。下次再调用shareInstance时onceToken为-1直接跳过block。 1.3.2 饿汉式 当类被加载的时候就创建因为一个类在整个生命周期中只会被加载一次所以它肯定只有一个线程对其进行访问此时再创建他就是线程安全的就不需要使用线程锁来保证其不会被多次创建。 static id manager nil; (void)load {[super load];manager [[super allocWithZone:NULL] init]; } (instancetype)shareInstance {return manager; }- (instancetype)copyWithZone:(NSZone *)zone {return manager; }- (instancetype)mutableCopyWithZone:(NSZone *)zone {return manager; } (instancetype)allocWithZone:(struct _NSZone *)zone {return manager; }1.4 关于复写 根据单例的定义我们只能允许存在一个该单例对象所以我们要扼制其创建出新的该单例类的对象保证对象的唯一性。所以我们要复写一些可以自己创建对象的方法例如copy、mutableCopy。为了彻底保证用户无法创建新的该单例类的对象我们一般会重写到XXXWithZone:方法。 - (instancetype)copyWithZone:(NSZone *)zone {return manager; }- (instancetype)mutableCopyWithZone:(NSZone *)zone {return manager; } (instancetype)allocWithZone:(struct _NSZone *)zone {return manager; }2 通知 2.1 几个点 观察者和被观察者都无需知晓对方只需要通过标记在NSNotificationCenter中找到监听该通知所对应的类从而调用该类的方法。并且在NSNotificationCenter中观察者可以只订阅某一特定的通知并对齐做出相应操作而不用对某一个类发的所有通知都进行更新操作。NSNotificationCenter对观察者的调用不是随机的而是遵循注册顺序一一执行的并且在该线程内是同步的。 2.2 通知使用步骤 总体分为三步走 在要传递参数的地方发送通知给通知中心: [[NSNotificationCenter defaultCenter] postNotificationName:temp object:nil userInfo:{content: self.myTextField.text}];在接收参数的地方注册通知并实现定义方法 [[NSNotificationCenter defaultCenter] addObserver:self selector:selector(Notificate:) name:temp object:nil];在不需要通知的时候移除通知 [[NSNotificationCenter defaultCenter] removeObserver:self];2.3 一些问题 2.3.1 通知的发送时同步的还是异步的发送消息与接收消息的线程是同一个线程么 通知中心发送通知给观察者是同步的也可以用通知队列NSNotificationQueue异步发送通知。 在抛出通知以后观察者在通知事件处理完成以后可以通过休眠3秒来测试抛出者才会往下继续执行也就是说这个过程默认是同步的当发送通知时通知中心会一直等待所有的 observer 都收到并且处理了通知才会返回到 poster。 接收通知的线程和发送通知所处的线程是同一个线程。也就是说如果要在接收通知的时候更新 UI需要注意发送通知的线程是否为主线程。 - (void)viewDidLoad {[super viewDidLoad];[[NSNotificationCenter defaultCenter] addObserver:self selector:selector(test) name:NotificationName object:nil]; }- (void)touchesBegan:(NSSetUITouch * *)touches withEvent:(UIEvent *)event {dispatch_queue_t queue dispatch_queue_create(test.queue, DISPATCH_QUEUE_SERIAL);dispatch_async(queue, ^{NSLog(--currect thread:%, [NSThread currentThread]);NSLog(Begin post notification);[[NSNotificationCenter defaultCenter] postNotificationName:NotificationName object:nil];NSLog(End);}); }- (void)test {NSLog(--current thread:%, [NSThread currentThread]);NSLog(Handle notification and sleep 3s);sleep(3); }2.3.2 如何使用异步发送通知 让通知事件处理方法在子线程中执行。 - (void)viewDidLoad {[super viewDidLoad];[[NSNotificationCenter defaultCenter] addObserver:self selector:selector(test) name:NotificationName object:nil]; }- (void)touchesBegan:(NSSetUITouch * *)touches withEvent:(UIEvent *)event {NSLog(--currect thread:%, [NSThread currentThread]);NSLog(Begin post notification);[[NSNotificationCenter defaultCenter] postNotificationName:NotificationName object:nil];NSLog(End); }- (void)test {dispatch_queue_t queue dispatch_queue_create(test.queue, DISPATCH_QUEUE_SERIAL);dispatch_async(queue, ^{NSLog(--currect thread:%, [NSThread currentThread]);NSLog(Handle notification and sleep 3s);sleep(3);NSLog(Test End);}); }可以通过 NSNotificationQueue 的 enqueueNotification: postingStyle: 和 enqueueNotification: postingStyle: coalesceMask: forModes: 方法将通告放入队列实现异步发送在把通告放入队列之后这些方法会立即将控制权返回给调用对象。 - (void)viewDidLoad {[super viewDidLoad];[[NSNotificationCenter defaultCenter] addObserver:self selector:selector(test) name:NotificationName object:nil]; }- (void)touchesBegan:(NSSetUITouch * *)touches withEvent:(UIEvent *)event {NSLog(--current thread:%, [NSThread currentThread]);NSLog(Begin post notification);NSNotification *notification [NSNotification notificationWithName:NotificationName object:nil];[[NSNotificationQueue defaultQueue] enqueueNotification:notification postingStyle:NSPostASAP];NSLog(End); }- (void)test {NSLog(--current thread:%, [NSThread currentThread]);NSLog(Handle notification and sleep 3s);sleep(3);NSLog(Test End); }2.3.3 NSNotificationQueue 和 runloop 的关系 postringStyle 参数就是定义通知调用和 runloop 状态之间关系。 该参数的三个可选参数 1.NSPostWhenIdle通知回调方法是等待到当下线程 runloop 进入等待状态才会调用。 2.NSPostASAP通知回调方法是等待到当下线程 runloop 开始接收事件源的时候就会调用。 3.NSPostNow其实和直接用默认的通知中心添加通知是一样的通知马上调用回调方法。 2.3.3 页面销毁时不移除通知会崩溃吗 在观察者对象释放之前需要调用 removeOberver 方法将观察者从通知中心移除否则程序可能会出现崩溃。但从 iOS9 开始即使不移除观察者对象程序也不会出现异常。 这是因为在 iOS9 以后通知中心持有的观察者由 unsafe_unretained 引用变为weak引用。即使不对观察者手动移除持有的观察者的引用也会在观察者被回收后自动置空。但是通过 addObserverForName:object: queue:usingBlock: 方法注册的观察者需要手动释放因为通知中心持有的是它们的强引用。 2.3.4 多次添加同一个通知会是什么结果多次移除通知呢 多次添加同一个通知观察者方法会调用多次多次移除没关系。 2.3.5 为什么注册通知时可以空名注册但是发送通知时却不可以 当注册通知时空的通知名称表示监听所有的通知。这在某些情况下是非常有用的特别是当你希望监听某个对象发送的所有通知时而不仅限于特定的通知名称。发送通知时不可以使用空的通知名称这是因为发送通知时需要指定一个具体的通知名称以便通知中心能够将通知正确地发送给对应的观察者。如果在发送通知时使用空的通知名称通知中心将无法确定通知应该发送给哪些观察者这样会导致通知无法被正确处理。 2.3.6 object是干嘛的?是不是可以用来传值? 在观察者的添加中object 参数指定了通知的发送者只有当通知的发送者与观察者添加时指定的 object 参数相同才会接收到通知。如果观察者添加时指定了具体的 object 对象那么在发送通知时通知的 object 参数必须与观察者添加时的 object 参数相匹配否则观察者将不会接收到通知。如果需要传值请用userInfo而不是object。 示例以下方法就不会接收到通知 // 添加观察 [[NSNotificationCenter defaultCenter] addObserver:self selector:selector(handleNotification:) name:TestNotification object:1]; // 通知发送 [NSNotificationCenter.defaultCenter postNotificationName:TestNotification object:nil];这是因为在添加观察者时指定了 object 参数为 1即一个 NSNumber 类型的对象。而在发送通知时指定的 object 参数为 nil。 3 代理 3.1 代理的使用步骤 在B视图控制器声明一份协议 protocol MyViewControllerDelegate NSObject- (void)changUILabelText:(NSString *)string;end在B视图控制器中声明一个代理属性 property (nonatomic, weak) idMyViewControllerDelegate delegate;在B视图控制器中想要回传值的地方写代理执行的方法 [self.delegate changeUILabelText:self.myTextField.text];在A视图控制器里签订代理协议 interface ViewController : UIViewController MyViewControllerDelegateproperty (nonatomic, strong) MyViewController *myView;endA中签订代理人 self.myView [[MyViewController alloc] init];self.myView.delegate self;实现协议方法 - (void)changUILabelText:(NSString *)string {NSLog(%, string); }3.2 代理的循环引用 代理的循环引用是指在代理模式中由于相互强引用导致两个对象通常是委托方和代理方之间形成了一个循环引用的关系从而导致内存泄漏问题。由于这种循环引用当委托方和代理方相互强引用对方时它们的引用计数无法降为0导致它们所占用的内存无法被正确释放从而造成内存泄漏。 为了避免代理的循环引用可以采用以下几种方法之一 使用弱引用weak reference在委托方的属性声明中将代理方的引用设为弱引用这样就不会形成循环引用。例如property (nonatomic, weak) id delegate;。但需要确保代理方在使用期间不会被提前释放。使用代理方的生命周期控制在委托方中持有代理方的引用时可以根据具体情况在适当的时候解除对代理方的引用避免循环引用。使用 block 或通知来替代代理模式在某些情况下可以使用 block 或通知来替代代理模式避免循环引用的问题。 选择合适的方法取决于具体的业务逻辑和需求确保代理模式的使用不会造成循环引用和内存泄漏。 4. KVO\KVC\单例模式\通知\代理\Block 4.1 代理和通知的区别 效率代理比通知高关联代理是强关联委托和代理双方互相知道。通知是弱关联不需要知道是谁发也不需要知道是谁接收代理是一对一的关系通知是一对多的关系代理要实现对多个类发出消息可以通过将代理者添加入集合类后遍历或通过消息转发来实现。代理一般行为需要别人来完成通知是全局通知 4.2 KVO和通知的区别 相同都是一对多的关系不同通知是需要被观察者先主动发出通知观察者注册监听再响应比KVO多了发送通知这一步监听范围KVO是监听一个值的变化通知不局限于监听属性的变化还可以对多种多样的状态变化进行监听通知的监听范围广使用更灵活使用场景KVO的一般使用场景是监听数据变化通知是全局通知 4.3 block和代理的区别 相同点block和代理都是回调的方式。使用场景相同。不同点 block集中代码块而代理分散代码块所以 block 更适用于轻便、简单的回调如网络传输代理适用于公共接口较多的情况这样做也更易于解耦代码架构block运行成本高block出栈时需要将使用的数据从栈内存拷贝到堆内存。当然如果是对象就是加计数使用完或block置为 nil 后才消除而代理只是保存了一个对象指针直接回调并没有额外消耗相对C的函数指针只是多做了一个查表动作 总结表 方法delegateNSNotificationKVOblock优点1.逻辑清楚2代码可读性较强3.编译器会检查是否实现了所有方法4.-个controller可以有多个协议5.减少代码耦合性1.代码量小2.可以实现一对多3.传值方便快捷1.可以简单的实现两个对象同步2.可以观察当前值和先前值3.能够对非我们创建的对象即内部对象的状态改变作出响应而且不需要改变内部对象SDK对象的实现1.逻辑清晰2.同一函数需要低啊用多次的时候节省代码量3.block可以存储在属性里4.增强代码可读性5.配合GCD优秀的解决多线程缺点1.定义需要的代码多2.释放时需要将delegate置为nil否则调用释放的delegate会crash3.一个controller有多个同一协议的deleqate.难以区分4.跨层传值监听会使程序层次混乱5.容易引起循环引用1.编译器不会发现是否可以正确处理2.释放注册对象时需要取消注册否则可能会crash3.逻辑不清晰1.观察的属性使用“string”编译器不会出现警告和检查编译器无法在编译时捕获拼写错误或其他错误类型2.属性重构后需要再次修改属性名称变更、属性类型变更、属性移除或新增1.可能引起循环引用2.block中的代码会自动retain.容易造成内存泄漏建议使用场景controller与其他任何对象通信回调方法中一对多的情况、UI响应事件代码上需要处理的东西很简单两个毫无关联的对象之间通信需要监视一个属性回调方法简单值的传递 5 设计模式总结 KVO/通知 ------- 观察者模式 观察者模式定义了一种一对多的依赖关系让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时会通知所有观察者对象使它们能够自动更新自己。 优势解耦合 接口隔离原则、开放-封闭原则 KVC -------- KVC模式 KVC 提供了一种更加灵活和强大的属性访问方式使得开发者能够以简单的方式操作对象的属性和集合减少了许多重复的代码和复杂性。它是 Cocoa 框架中的一个重要特性为开发者带来了便利和高效性。但需要注意的是使用 KVC 时需要保证对象的属性符合 KVC 规范即属性通过一定的命名规则对应到键这样才能正确地使用 KVC 进行属性访问和操作。 单例模式 利用应用程序只有一个该类的实例对象这一特殊性来实现资源共享。 优势使用简单延时求值易于跨模块 劣势这块内存知道程序退出时才能释放 单一职责原则 代理模式 委托方将不想完成的任务交给代理方处理并且需要委托方通知代理方才能处理。 优势 解耦合 开放-封闭原则 举例tableview的数据源和代理 策略模式 策略模式定义了一系列的算法并将每一个算法封装起来而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。 优势使算法的变化独立于使用算法的用户 接口隔离原则、多用组合少用继承、针对接口编程而非实现 举例账号密码输入格式的判断、NSArray的sortedArrayUsingSelector等等 MVC模式 将程序书写分为三层分别为模型、视图、控制器每层都有各自的职责完成各自的工作。 优势 MVC模式使系统层次清晰职责分明易于维护 对扩展开放-对修改封闭 MVVM模式 用于解决MVC模式下C层代码冗杂的情况过多的网络请求以及业务逻辑处理而出现的MVVM模式其相比于MVC多了一层ViweModel业务处理和数据转化层专门用于处理数据。 当功能简单时MVVM反而会增加很多代码所以对于简单的功能MVC更加的方便。 三种工厂模式 通过给定参数来返回对应的实例完全对用户隐藏其实现的原理。 优势易于替换面向抽象编程 依赖倒置原则 设计模式MVC模式、单例模式、观察者模式、MVVM模式、工厂模式、代理模式、策略模式 适配器模式、模板模式、外观模式、创建模式 想要深入了解可以看看这个iOS 设计模式
http://www.ho-use.cn/article/10823989.html

相关文章:

  • 旅游网站建设毕业设计满山红网站建设
  • 常州北京网站建设网站搜索栏怎么做
  • 厦门建网站做优化馆陶网站建设费用
  • 杭州企业网站seo如何给wordpress写权限
  • 网站建设数据库是什么意思memcached集群WordPress
  • 网站开发试题东莞正规制作网站公司吗
  • 高校门户网站的建设方案网站建设收费标准
  • 网站维护服务费discuz 做门户网站
  • 到哪里查网站备案信息做网站需学什么条件
  • 青岛私人做网站wordpress收款
  • 中国门户网站建设重要性做网站需要学哪些语言
  • 招聘网站可做哪些推广方案广州网站开发 细致广州亦客网络
  • 新手怎么样学做网站简单的app开发
  • 织梦门户网站源码下载小型网站建设公司
  • 宝山做网站价格百度免费校园网站建设
  • 兼职网站建设收费网app开发
  • 德洲网站建设如何在网上推广信用卡
  • 亚马逊amz123seo引擎优化
  • 领先的响应式网站建设平台全网推广的方式
  • 如何做聚合类网站wordpress支持python吗
  • 网站改了模板被百度降权最便宜做个网站多少钱
  • 给钱做任务的网站重庆seo推广外包
  • 设计主题网站怎样看一个网站的信息吗
  • 织梦网站管理系统小说推广合作平台入口
  • 网站设计步骤大全萧山区建设工程质量监督站网站
  • 中国建设教育协会培训中心网站站优化
  • 做网站生意多吗短网址助手
  • 什么网站收录快关键词优化seo费用
  • 平台网站怎么优化中搜seo
  • 商城网站功能介绍建设网站要求有哪些