swift之block的循环引⽤ViewController
#import "ViewController.h"
#import "NetworkTools.h"
/*
接触循环引⽤打破引⽤循环即可
1.不使⽤成员变量来调⽤闭包
2.__weak or __unsafe_unretained
*/
@interface ViewController ()
@property (nonatomic, strong) NetworkTools *tools;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//加载⽹络数据
//以后⼯作中⼤家会看到⼤量以下代码
//不会有任何不同
//将⼀个弱引⽤的对象在闭包中变成强引⽤的对象希望在对象self在被回收时记录self 以便能够继续访问⽅法 //但是就是个棒槌没有任何作⽤
__unsafe_unretained typeof(self) weakSelf = self;
[ls loadData:^(NSString *html) {
__strong typeof(self) strongSelf = weakSelf;
NSLog(@"data = %@",html);
NSLog(@"%@",strongSelf.view);
}];
}
- (void) method2 {
//加载⽹络数据
//定义block的时候在block中使⽤了外部变量会默认做copy操作
//会对self进⾏强引⽤
接触循环引⽤的⽅法⼆
// __weak 相当于 weak关键字修饰当对象被回收时对象地址会⾃动指向nil 给nil发送消息在OC中是可以的 //不会造成野指针访问
//iOS 5.0之后推出的
__weak typeof(self) weakSelf = self;
// __unsafe_unretained typeof(self) weakSelf = self;
[ls loadData:^(NSString *html) {
NSLog(@"data = %@",html);
//现在会产⽣循环引⽤嘛?
NSLog(@"%@",weakSelf.view);
}];
}
- (void) method1 {
//加载⽹络数据
//定义block的时候在block中使⽤了外部变量会默认做copy操作
//定义block的时候在block中使⽤了外部变量会默认做copy操作
//会对self进⾏强引⽤
// __weak typeof(self) weakSelf = self;
//接触循环引⽤的⽅法1
//__unsafe_unretained 相当于assgin关键字修饰当对象被回收是对象地址不会指向nil //iOS 4.0推出的
//会导致坏地址访问俗称野指针
__unsafe_unretained typeof(self) weakSelf = self;
[ls loadData:^(NSString *html) {
NSLog(@"data = %@",html);
//现在会产⽣循环引⽤嘛?
NSLog(@"%@",weakSelf.view);
}];
}
NetworkTools.h
#import <Foundation/Foundation.h>
@interface NetworkTools : NSObject
//定义⽹络访问⽅法
- (void) loadData:(void(^)(NSString *html))finished;
@end
NetworkTools.m
#import "NetworkTools.h"
@interface NetworkTools ()
@property (nonatomic, copy) void (^finishedBlock)(NSString *);
@end
@implementation NetworkTools
//block是⼀组准备好的代码在需要的时候执⾏
//可以当做参数传递
//在异步⽅法中如果能直接执⾏block就直接执⾏
//如果不需要⽴即执⾏就需要⽤⼀个属性来记录block 在需要的时候执⾏//finished执⾏完就解除了对self的强引⽤
- (void)loadData:(void (^)(NSString *))finished {
//记录block
self.finishedBlock = finished;
//异步加载数据
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//睡 3秒
[NSThread sleepForTimeInterval:3];
//耗时任务结束后主线程完成回调
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"回调数据");typeof的用法
// finished(@"终于拿到数据");
[self working];
});
});
}
- (void) working {
//在调⽤block的时候需要判断是否为空
if (self.finishedBlock) {
self.finishedBlock(@"回调数据");
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论