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

宠物网站建设策划书有没有做a的电影网站

宠物网站建设策划书,有没有做a的电影网站,后台网站模板html,吉林天宇建设集团网站循环引用 文章目录 循环引用1.自循环引用2.相互循环引用3.多循环引用 常见的循环引用问题1.delegate解决方法#xff1a; 2.block解决方法#xff1a;1.强弱共舞2.把当前类作为block的参数3.用__block修饰变量#xff0c;在block内部置nil 3.NSTimer解决方案#xff1a;1.使…循环引用 文章目录 循环引用1.自循环引用2.相互循环引用3.多循环引用 常见的循环引用问题1.delegate解决方法 2.block解决方法1.强弱共舞2.把当前类作为block的参数3.用__block修饰变量在block内部置nil 3.NSTimer解决方案1.使用中间类2.使用类方法3.使用 weakProxy4.改用block类型的定时器API 对象A和对象B相互引用了对方作为自己的成员变量只有当自己销毁时才会将成员变量的引用计数减1这就导致了A的销毁依赖于B的销毁同样B的销毁依赖于A的销毁这样就造成了循环引用问题。 1.自循环引用 假如有一个对象内部强持有它的成员变量obj若此时我们给obj赋值为原对象时就是自循环引用。 2.相互循环引用 对象A内部强持有obj对象B内部强持有obj若此时对象A的obj指向对象B同时对象B中的obj指向对象A就是相互引用。 3.多循环引用 假如类中有对象1…对象N每个对象中都强持有一个obj若每个对象的obj都指向下个对象就产生了多循环引用。 常见的循环引用问题 1.delegate 我们平时经常用的协议传值如果我们委托方的delegate属性使用strong强引用就会造成代理方和委托方互相强引用出现循环引用问题。代理方强引用委托方对象并且委托方对象中的delegate属性又强引用代理方对象这就造成了循环引用问题。 property (nonatomic, strong) id MyDelegate delegate;解决方法 需要将委托方的delegate属性改为weak修饰就行了这样委托方的delegate就不会强引用代理方对象了简单解决了这个循环引用问题。 property (nonatomic, weak) id MyDelegate delegate;2.block 不是所有的block都会循环引用我们需要判断什么情况会循环引用xcode会给出warning //self - reachabilityManager - block - self 都是循环引用self.reachabilityManager.stateBlock ^(int number){NSLog(%,self. reachabilityManager);}; //或者block内部没有显式地出现self只要你在block里用到了self所拥有的东西一样会出现循环引用self.reachabilityManager.stateBlock ^(int number){NSLog(%,_ reachabilityManager);};要判断block是否造成了循环引用我们要看block中的引用的变量和block外部引用block的变量会不会形成一个强引用的闭环以此来判断block是否造成了循环引用的问题。 解决方法 1.强弱共舞 解决它其实很简单无非就是self引用了blockblock又引用了self让他们其中一个使用weak修饰不就行了 - (void)touchesBegan:(NSSetUITouch * *)touches withEvent:(UIEvent *)event{[self dismissViewControllerAnimated:YES completion:nil];__weak typeof(self) weakSelf self;void (^Block) (void) ^{dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{NSLog(%, weakSelf);});};Block(); }但是仅仅使用__weak修饰self存在一个缺陷__weak可能会导致内存提前回收weakSelf在未执行NSLog()时weakSelf就已经被释放了(例如上述情况)然后执行NSLog()时就打印(null)。 所以为了解决这个缺陷我们需要这样在block内部再用__strong去修饰weakSelf - (void)touchesBegan:(NSSetUITouch * *)touches withEvent:(UIEvent *)event{[self dismissViewControllerAnimated:YES completion:nil];__weak typeof(self) weakSelf self;void (^Block) (void) ^{__strong typeof(self) strongSelf weakSelf;dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{NSLog(%, strongSelf);});};Block(); } 我们发现上述这个方法确实解决所有问题但是可能会有两个不理解的点 即使用weakSelf又使用strongSelf这么做和直接用self有什么区别为什么不会有循环引用这是因为block外部的weakSelf是为了打破环循环引用而block内部的strongSelf是为了防止weakSelf被提前释放strongSelf仅仅是block中的局部变量在block执行结束后被回收不会再造成循环引用。 这么做和使用weakSelf有什么区别唯一的区别就是多了一个strongSelf而这里的strongSelf会使self的引用计数1使得self只有在block执行完局部的strongSelf被回收后self才会dealloc。 2.把当前类作为block的参数 - (void)touchesBegan:(NSSetUITouch * *)touches withEvent:(UIEvent *)event {void (^Block) (ViewController *) ^(ViewController *vc){dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{NSLog(%, vc);});};Block(self); }3.用__block修饰变量在block内部置nil __block Person *person [[Person alloc] init];person.age 20;person.newblock ^{NSLog(%d, person.age);person nil;};person.newblock();3.NSTimer NSTimer也会出现很多经典的循环引用问题 - (void)viewDidLoad {[super viewDidLoad];self.myTimer [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:selector(doSomething) userInfo:nil repeats:YES]; }- (void)doSomething {}- (void)dealloc {[self.myTimer invalidate];self.myTimer nil; }这个问题用上面两种的weak就无法解决因为不管是weakSelf还是strongSelf最终Runloop强引用NSTimer其也就间接的强引用了对象结果就会导致循环引用。 两种解决方法 让视图控制器对NSTimer的引用变成弱引用让NSTimer对视图控制器的引用变成弱引用 第一种方法如果控制器对NSTimer的引用改为弱引用则会出现NSTimer直接被回收所以不可使因此我们只能从第二种方法入手。 解决方案 1.使用中间类 创建一个继承NSObject的子类MyTimerTarget并创建开启计时器的方法。 // MyTimerTarget.h #import Foundation/Foundation.h interface MyTimerTarget : NSObject(NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)interval target:(id)target selector:(SEL)selector userInfo:(id)userInfo repeats:(BOOL)repeats; end// MyTimerTarget.m #import MyTimerTarget.h interface MyTimerTarget () property (assign, nonatomic) SEL outSelector; property (weak, nonatomic) id outTarget; endimplementation MyTimerTarget(NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)interval target:(id)target selector:(SEL)selector userInfo:(id)userInfo repeats:(BOOL)repeats {MyTimerTarget *timerTarget [[MyTimerTarget alloc] init];timerTarget.outTarget target;timerTarget.outSelector selector;NSTimer *timer [NSTimer scheduledTimerWithTimeInterval:interval target:timerTarget selector:selector(timerSelector:) userInfo:userInfo repeats:repeats];return timer; } - (void)timerSelector:(NSTimer *)timer {if (self.outTarget [self.outTarget respondsToSelector:self.outSelector]) {[self.outTarget performSelector:self.outSelector withObject:timer.userInfo];} else {[timer invalidate];} } end// 调用方 interface ViewController () property (nonatomic, strong) NSTimer *myTimer; endimplementation ViewController - (void)viewDidLoad {[super viewDidLoad];self.myTimer [MyTimerTarget scheduledTimerWithTimeInterval:1 target:self selector:selector(doSomething) userInfo:nil repeats:YES]; }- (void)doSomething {}- (void)dealloc {NSLog(MyViewController dealloc); } endVC强引用timer因为timer的target是MyTimerTarget实例所以timer强引用MyTimerTarget实例而MyTimerTarget实例弱引用VC解除循环引用。这种方案VC在退出时都不用管timer因为自己释放后自然会触发timerSelector:中的[timer invalidate]逻辑timer也会被释放。 2.使用类方法 我们还可以对NSTimer做一个category通过block将 timer的target和selector绑定到一个类方法上来实现解除循环引用 // NSTimerMyUtil.h #import Foundation/Foundation.h interface NSTimer (MyUtil)(NSTimer*)MyUtil_scheduledTimerWithTimeInterval:(NSTimeInterval)interval block:(void(^)(void))block repeats:(BOOL)repeats; end// NSTimerMyUtil.m #import NSTimerMyUtil.h implementation NSTimer (MyUtil)(NSTimer *)MyUtil_scheduledTimerWithTimeInterval:(NSTimeInterval)interval block:(void(^)(void))block repeats:(BOOL)repeats {return [self scheduledTimerWithTimeInterval:interval target:self selector:selector(MyUtil_blockInvoke:) userInfo:[block copy] repeats:repeats]; } (void)MyUtil_blockInvoke:(NSTimer *)timer {void (^block)(void) timer.userInfo;if (block) {block();} } end// 调用方 interface ViewController () property (nonatomic, strong) NSTimer *myTimer; end implementation ViewController- (void)viewDidLoad {[super viewDidLoad];self.myTimer [NSTimer MyUtil_scheduledTimerWithTimeInterval:1 block:^{NSLog(doSomething);} repeats:YES]; } - (void)dealloc {if (_myTimer) {[_myTimer invalidate];}NSLog(MyViewController dealloc); } end这种方案下VC强引用timer但是不会被timer强引用但有个问题是VC退出被释放时如果要停掉timer需要自己调用一下timer的invalidate方法。 3.使用 weakProxy 创建一个继承NSProxy的子类MyProxy并实现消息转发的相关方法。NSProxy是iOS开发中一个消息转发的基类它不继承自NSObject。因为他也是Foundation框架中的基类通常用来实现消息转发我们可以用它来包装NSTimer的target达到弱引用的效果。 //TestNSproxy.h中 #import Foundation/Foundation.hNS_ASSUME_NONNULL_BEGINinterface TestNSproxy : NSProxyproperty (nonatomic, weak) id target; (instancetype)proxyWithTarget:(id)target;endNS_ASSUME_NONNULL_END//TestNSproxy.m中 #import TestNSproxy.himplementation TestNSproxy//实现我们的类方法创建一个TestNSproxy类型的对象然后将传入的参数作为target便于后续的消息转发(instancetype)proxyWithTarget:(id)target {TestNSproxy *proxy [TestNSproxy alloc];proxy.target target;return proxy; }//下面实现第三次消息拯救中的那两个方法 - (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {return [self.target methodSignatureForSelector:sel]; }- (void)forwardInvocation:(NSInvocation *)invocation {[invocation invokeWithTarget:self.target]; }end//作为中间类作为timer的target的时候 //只需要调用TestProxy类的类方法时将参数传成当前界面的self即可 _timer [NSTimer scheduledTimerWithTimeInterval:1 target:[TestNSproxy proxyWithTarget:self] selector:selector(timerSelector) userInfo:nil repeats:YES]; 4.改用block类型的定时器API 结合self强弱共舞的方法来解决循环引用问题使得定时器可以及时释放。而且对于CADisplayLink和NSTimer来说无论外面传递的target是弱指针还是强指针都会传入一个内存地址定时器内部都是对这个内存地址产生强引用所以传递弱指针没有用。 // 让 timer 对self 产生弱引用__weak typeof(self) weakSelf self;self.timer [NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {[weakSelf test];}];
http://www.pierceye.com/news/126848/

相关文章:

  • 安顺建设局网站官网哪里有响应式网站企业
  • 唯品会一家做特卖的网站国家商标查询官方网站
  • 网站宝搭建网站环境做电商网站一般需要什么流程图
  • 南通网站建设团队wordpress广告产检
  • 做网站刷赞qq怎么赚钱邢台路桥建设总公司没有网站吗
  • 网站仿站教程常用外贸网站
  • 南昌市有帮做网站的吗纵横天下网站开发
  • pc网站直接转换成移动端的网站黑果云免费虚拟主机
  • 网站建设用什么科目wordpress当前分类链接地址
  • 做一万个网站网站做下载功能
  • 佛山建站模板制作wordpress加上live2d
  • 樟木头网站仿做深圳网站开发公司
  • 孙俪做的网站广告微信如何修改wordpress
  • 有什么手机做网站的免费ppt模板下载花
  • 网站建设团队技术介绍县级网站
  • 深圳营销型网站建设价格网站建设文化如何
  • 提交网站的入口地址网站建设灬金手指下拉十五
  • 连云港建设局网站学校网站建设管理相关规定
  • 什么网站做玩具的外贸网站监控系统
  • 从事网站美工建设厦门网站制作企业
  • 网站后台传图片南昌做网站要多少钱
  • 网站包括什么国内最大的域名交易平台
  • 做营销型网站 公司哈尔滨展览设计公司
  • 网站设计费用多少钱产品网页设计教程
  • 深圳公司网站建设设计网站推广的意义和方法
  • 网站需要哪些费用免费营销型网站模版
  • 如何做购物网站的教程wordpress酷炫插件
  • 建设信用卡网站登录网站建设和微信小程序
  • 邓州企业网站艺术设计方案
  • 广州市住房住建局网站永久免费的云电脑