—————自定义视图
①初始化②调用
①-(instancetype)initWithFrame:(CGRect)frame labelText:(NSString *)textplaceholder:(NSString *)holder delegate:(id<UITextFieldDelegate>)delegate
{
self = [super initWithFrame:frame];
if (self) {
UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, kWidth/4, kHeight)];
label.text = text;
[self addSubview:label];// self就是本身的LTView的对象??
[label release];
// textField
UITextField * textField = [[UITextFieldalloc] initWithFrame:CGRectMake(kWidth/4, 0, kWidth*3/4, kHeight)];
textField.placeholder = holder;
textField.borderStyle =UITextBorderStyleRoundedRect;
textField.delegate = delegate;
[self addSubview:textField];
[textField release];
}
return self;
}
② LTView * view = [[LTView alloc]initWithFrame:CGRectMake(50, 100, 240, 30) labelText:@"用户名" placeholder:@"电话号码"delegate:self];// 此时self就是Appdelegate这个类的一个实例对象
[_window addSubview:view];
[view release];
——————触摸 注意: UILabel.UIImageView它们的userIteractionEnabel默认是NO,其他的全部是YES
// target....action只能对应一个时间点,是一对一的,是最好的方法
// 如果需求是对应多个时间点,那么需要使用代理协议模式
TouchView.h
@property(nonatomic,retain)id target;// 创建执行对象
@property(nonatomic,assign)SEL action;// 创建执行方法
@property(nonatomic,retain)id<TouchViewDelegate> delegate;
TouchView.m
-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent *)event
{
if ([_delegaterespondsToSelector:@selector(touchViewTouchBegan:)]) {
[_delegate touchViewTouchBegan:self];
}
}
创建视图后; _touchView1.target = self;
_touchView1.action =@selector(changeColor:);
_touchView1.delegate = self;
———————创建警示框
UIAlertController * alertC =[UIAlertController alertControllerWithTitle:@"提示"message:@"登录失败"preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction * actoin1 = [UIAlertActionactionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction*action) {
NSLog(@"您点击了取消按钮");
}];
NSLog(@"%lu",self.retainCount);
__block RootViewController * rootVC =self;// 释放rootVC.textField.text = nil;
UIAlertAction * actoin2 =[UIAlertAction actionWithTitle:@"重新登录" style:UIAlertActionStyleDefaulthandler:^(UIAlertAction *action) {
rootVC.textField.text =@"";// 是对当前的类的引用计数加1
}];
NSLog(@"%lu",self.retainCount);
[alertC addAction:actoin1];
[alertC addAction:actoin2];
[self presentViewController:alertCanimated:YES completion:nil];// 推出AlertC 要是没有那就没法显示
———————滚动视图
self.scrollview =[[UIScrollView alloc] initWithFrame:CGRectMake(30, 100, 320, 480)];
_scrollview.backgroundColor = [UIColorredColor];
// 设置分页效果
_scrollview.pagingEnabled = YES;// 默认为NO
// 设置scrollView的内容区域大小(可滚动范围)
_scrollview.contentSize =CGSizeMake(21*_scrollview.frame.size.width, _scrollview.frame.size.height);
for (int i = 0; i < 21; i++) {
NSString * imageNamed = [NSString stringWithFormat:@"image%d.jpg",i+1];
UIImage * image = [UIImageimageNamed:imageNamed];
UIImageView * imageView = [[UIImageViewalloc] initWithFrame:CGRectMake(KWidth * i,0, KWidth, KHeight)];
imageView.image = image;
[_scrollview addSubview:imageView];
[imageView release];
}
[self.view addSubview:_scrollview];
[_scrollview release];
————代理传值
// 1⃣️ 制定协议 - (void)sendValue:(NSString *)text;
// 2⃣️ 遵守协议 @interface LoginViewController :UIViewController<ReginsterViewControllerDelegate>
// 3⃣️ 实现协议中的方法
- (void)sendValue:(NSString*)text
{
_label.text = text;
}
// 4⃣️ 设置代理 rigisterVC.delegate = self;
// ��️声明一个代理属性(因为reginsterVC是委托人,他要拥有一个delegate属性,用来设置代理
@property(nonatomic,assign)id<ReginsterViewControllerDelegate>delegate;
// 6⃣️respondsToSelector:检查sendValue:这个方法是否实现,如果没有实现,就不执行这个方法,否则,执行这个方法
if ([_delegate respondsToSelector:@selector(sendValue:)]){
[_delegate sendValue:_textField.text];
}
—————属性传值
//1. 此时进行属性传值 rigisterVC.text = _textField.text;
//2. 属性用来接收上级页面传过来的值@property (nonatomic,retain)NSString * text;
//3. 将传过来的值,显示在label上 _label.text = _text;
——————block传值(1.2在.h)
1.typedefvoid(^BLOCK)(NSString * text);重命名
2.@property(nonatomic,copy)BLOCKblock;声明为属性
3._block(_textField.text);此时传值到上一页面(调用block) Block_release(_block);block的释放
4.接收界面:
firstVC.block =^void(NSString *text){
[button setTitle:textforState:UIControlStateNormal]; //将下级页面传过来值,显示在button上
};内部实现即传值
———————单例(单例消耗内存,因此不建议多用)
1.创建一个单例类:声明属性 @property (nonatomic,retain)NSString * text;(要用到的值)
2.获取单例对象 声明 +(DataHandle *)sharedInstance; 实现:
① static DataHandle * dataHandle = nil;
② + (DataHandle *)sharedInstance{
// 同步锁(为了避免多个线程同时访问同一个资源,导致资源不统一)
@synchronized(self){
// 判断dataHandle为空时,创建一个,否则直接返回
if (dataHandle == nil) {
dataHandle = [[DataHandle alloc] init];
}
}
return dataHandle;
}
3.获取单例对象 DataHandle *handel = [DataHandle sharedInstance];
4.将值存入单例对象的text属性 handel.text = _textfield.text;
5.获取单例对象 DataHandle *handle = [DataHandle sharedInstance];
6.获取单例对象的值 self.title =handle.text;
———————UITableViewController编辑解析本地文件 plist
注意:在viewController里创建tabelView遵守UITableViewDataSource,UITableViewDelegate 可以实现tabelView相关属性
1.创建model类 声明属性(属性必须和plist文件名字一致),在.m写上- (void)setValue:(id)valueforUndefinedKey:(NSString *)key{} 防止属性不全崩溃
2.TableViewController声明model类属性
3.设置其他(eg:_tableView.delegate= self; _tableView.dataSource = self;) 相关属性后 注意4需要重用
4.cell重用
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
UITableViewCell *cell = [tableViewdequeueReusableCellWithIdentifier:@"cell"];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"];
}
// 设置显示内容
NSLog(@"%@",_city.name);
cell.textLabel.text = _city.name;
return cell;
}
——————重写setter方法一般在需要赋值的时候重写setter方法
- (void)setStudent:(Student*)student{
if (_student != student) {
[_student release];
_student = [student retain];// ?为什么retain
// 赋值
_headerImageView.image = [UIImageimageNamed:_student.photo];
_phoneLabel.text = _student.phone;
_nameLabel.text = _student.name;
_hobbyLabel.text = _student.hobby;
}
}
——————模态推出返回(可做特殊效果)
[selfpresentViewController:NC animated:YES completion:^{NSLog(@"模态推出!");}];
[selfdismissViewControllerAnimated:YES completion:^{NSLog(@"模态返回");}];
———————数据解析(JSON)
// 1.获取文件路径
NSString * fieldPath = [[NSBundlemainBundle] pathForResource:@"Teachers" ofType:nil];
// 2.读取文件,转换为NSData
NSData * data = [NSDatadataWithContentsOfFile:fieldPath];
// 3.解析
NSMutableArray * teacherArray =[NSJSONSerialization JSONObjectWithData:dataoptions:NSJSONReadingMutableContainers error:nil];
// 给老师数组开辟空间并初始化
self.teacherArray = [NSMutableArray array];
// 4.遍历数组
for (NSDictionary * dict in teacherArray) {
// 数组中又几个字典,表示我要创建几个Teacher对象
Teacher * teacher = [[Teacher alloc]init];
// 使用KVC赋值
[teachersetValuesForKeysWithDictionary:dict];
[_teacherArray addObject:teacher];
[teacher release];
}
———————网络编程,解析 遵循协议 NSURLConnectionDelegate,NSURLConnectionDataDelegate
// 1.网址对象(NSURL)
NSURL * url = [NSURLURLWithString:kPicURL];
// 2.请求对象(NSURLRequest)
NSURLRequest * request = [NSURLRequestrequestWithURL:url];
// 3.网络链接对象(NSURLConnection)
[NSURLConnectionconnectionWithRequest:request delegate:self];
// 4.实现以下协议
// 服务器已经开始响应
-(void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse *)response{
// 给recieveData开辟空间
self.recieveData = [NSMutableData data];}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
// 对每次传来的数据进行拼接
[_recieveData appendData:data];// 每来一点加载一点
self.ImageView.image = [UIImageimageWithData:_recieveData];}
———————异步下载图片 遵循协议NSURLConnectionDataDelegate,NSURLConnectionDelegate,AsynImageDownLoaderDelegate
1.创建协议 -(void)AsynImageDownLoader:(AsynImageDownLoader *)downLoader isLoading:(UIImage*)image;
2.在新建的model类里 .h遵循协议
- (instancetype)initWithImageUrl:(NSString*)imageUrl;
@property (nonatomic,assign)id<AsynImageDownLoaderDelegate>delegate;//代理属性
@property(nonatomic,assign)BOOL isDownLoading;// 判断是否正在下载
- (void)cancelRuquest;// 取消请求(主要为了防止多次重复提交请求)
3.2.在新建的model类里 .m
@property (nonatomic,retain)NSMutableData *recieveData;//用来接收传输过来的data数据
@property(nonatomic,retain)NSURLConnection * connection;// 声明连接对象
-(instancetype)initWithImageUrl:(NSString *)imageUrl
{
self = [super init];
if (self) {
// 1.获取网址对象
NSURL * url = [NSURLURLWithString:imageUrl];
// 2.请求对象
NSURLRequest * request = [NSURLRequestrequestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicytimeoutInterval:60.0];
// 3.连接对象并发送请求(注意:不需要接收值)
self.connection = [NSURLConnectionconnectionWithRequest:request delegate:self];
// 4.实现协议中的方法
}
return self;
}
-(void)connection:(NSURLConnection *)connectiondidReceiveResponse:(NSURLResponse *)response{
self.recieveData = [NSMutableData data];
}
// 已经正在接收数据
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
// 在这个方法中_isDownLoading = YES
_isDownLoading = YES;// 表示正在下载
[_recieveData appendData:data];
// self.imageView.image = [UIImageimageWithData:_recieveData];
UIImage * image = [UIImageimageWithData:_recieveData];
// [代理 执行协议中的方法:data(参数)]
if ([_delegaterespondsToSelector:@selector(AsynImageDownLoader:isLoading:)]) {
[_delegate AsynImageDownLoader:selfisLoading:image];
}
}
// 接收数据已经完成
-(void)connectionDidFinishLoading:(NSURLConnection*)connection{
_isDownLoading = NO;// 下载完毕
}
// 取消请求(主要为了防止多次重复提交请求)
- (void)cancelRuquest{
[_connection cancel];
}
4.在需要接收图片的.h文件里 遵守三个协议
5.在需要接收图片的.h文件里
@property(nonatomic,retain)NSMutableData * recieveData;//用来接收传输过来的data数据
AsynImageDownLoader *downLoader = [[AsynImageDownLoader alloc] initWithImageUrl:kPicURL];
downLoader.delegate = self;
// 实现协议中的方法
-(void)AsynImageDownLoader:(AsynImageDownLoader*)downLoader isLoading:(UIImage *)image{
self.imageView.image = image;
}
————————键值观察者
// 1. 注册观察者(为被观察者添加一个观察者并设置观察的属性)
[_person addObserver:selfforKeyPath:@"name" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:@"hello"];
// 2.改变属性name的值
_person.name = _texeField.text;
// 3.只要是被观察者的属性值发生变化,就会执行下面的这个方法
- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void*)context{
// 4. 取出新值和旧值(nil:空对象 @"":空字符串)
if (![change[@"new"]isEqualToString:change[@"old"]]) {
self.view.backgroundColor = [UIColor colorWithRed:arc4random()%256/255.0 green:arc4random() %256/255.0 blue:arc4random() %256/255.0alpha:1.0];
}
}
// 5.移除观察者
[_person removeObserver:selfforKeyPath:@"name" context:@"hello"];
————————复杂对象归档
// 复杂对象归档第一步:遵守NSCoding协议,在model类.h声明属性
@property(nonatomic,retain)NSString * name;
@property(nonatomic,retain)NSString * gender;
@property(nonatomic,assign)NSInteger age;
// 第二步:实现协议中的两个方法 在model类.m文件
#pragma mark ----进行编码
-(void)encodeWithCoder:(NSCoder*)aCoder{
[aCoder encodeObject:self.nameforKey:@"name"];
[aCoder encodeObject:_genderforKey:@"gender"];
[aCoder encodeInteger:_ageforKey:@"age"];
}
#pragma mark----进行反编码
-(id)initWithCoder:(NSCoder*)aDecoder{
self = [super init];// 注意:如果是在UI里面即View里面,是initWithFrame:frame
if(self) {
self.name = [aDecoderdecodeObjectForKey:@"name"];
_gender = [aDecoderdecodeObjectForKey:@"gender"];
_age = [aDecoderdecodeIntegerForKey:@"age"];
}
return self;
}
// 第三步 导入model类
#pragma mark--对复杂对象进行持久化
// 过程:(先有复杂对象->归档->NDData->writeToFile)
// 创建对象并赋值
Person * person = [[Person alloc] init];
person.name = @"王正羽";
person.gender = @"男";
person.age = 20;
// 归档
NSMutableData * data = [NSMutableDatadata];
// 创建归档器
NSKeyedArchiver * archiver =[[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
// 进行归档
[archiver encodeObject:personforKey:@"person"];
// 结束归档
[archiver finishEncoding];
// 将归档之后的NSData数据写入文件
// ① 存储路径
// 获取沙盒中Documents这个文件夹的路径
NSString * homePath = NSHomeDirectory();
// 获取Library/Caches文件夹的路径
NSString * cachesPath = [homePathstringByAppendingPathComponent:@"Library/Caches"];
// 拼接存储路径
NSString * personPath = [cachesPathstringByAppendingPathComponent:@"person.txt"];
// ② 根据路径写入文件
[data writeToFile:personPathatomically:YES];
NSLog(@"%@",personPath);
NSLog(@"%@",data);
#pragma mark--从文件中读取复杂对象
// 过程:(读取文件->NSData->反归档->复杂对象)
// 从文件中读取NSData数据
NSData * resultData = [NSData dataWithContentsOfFile:personPath];
// 创建反归档工具
NSKeyedUnarchiver * unarchiver =[[NSKeyedUnarchiver alloc] initForReadingWithData:resultData];
// 使用反归档工具对resultData数据进行反归档
Person * recievePerson = [unarchiverdecodeObjectForKey:@"person"];
// 结束反归档
[unarchiver finishDecoding];
NSLog(@"%@,%@,%ld",recievePerson.name,recievePerson.gender,recievePerson.age);
}
————————数据持久化
// 1.获取沙盒中Documents这个文件夹的路径
NSString * homePath =NSHomeDirectory();
// 拼接
NSString * documentsPath1 =[homePath stringByAppendingPathComponent:@"Documents"];
// 2.获取Library/Caches文件夹的路径
NSString * cachesPath =[homePath stringByAppendingPathComponent:@"Library/Caches"];
// 3.获得tmp文件夹的路径
NSString * tmpPath = [homePathstringByAppendingPathComponent:@"tmp"];
#pragma mark----对简单对象进行持久化
NSString * string = @"I loveyou";
//1. 拼接存储路径
NSString * strPath = [documentsPathstringByAppendingPathComponent:@"str.txt"];
// 2. 将字符串写入文件
[string writeToFile:strPath atomically:YESencoding:NSUTF8StringEncoding error:nil];// YES有安全措施,NO没有
// 读取文件中的字符串
NSString * str = [NSStringstringWithContentsOfFile:strPath encoding:NSUTF8StringEncoding error:nil];
// 将数组写入文件(字典同理)
NSArray * array =@[@"zhangsan",@"李四",@"123",@"!@#"];
// 拼接存储路径
NSString * arrayPath = [documentsPath stringByAppendingPathComponent:@"array.txt"];
// 写入文件
[array writeToFile:arrayPathatomically:YES];
// 从文件中读取方法
NSArray * array1 = [NSArrayarrayWithContentsOfFile:arrayPath];
// 将NSData数据持久化
UIImage * image = [UIImageimageNamed:@"8.jpg"];
NSData * data =UIImageJPEGRepresentation(image, 1.0);// 1.0保真参数,
// 存储路径
NSString * dataPath =[documentsPath stringByAppendingPathComponent:@"data.txt"];
// 写入文件
[data writeToFile:dataPath atomically:YES];
#pragma mark---NSFilemanager(文件管理类)
// 1.获取缓存文件夹所在路径
NSString * cachesPath1 =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES).lastObject;
// 创建一个字典
NSDictionary * dic1 =@{@"name":@"王正羽",@"sex":@"男"};
// 在cachesPath1路径下面创建一个文件夹
NSString * directroyPath = [cachesPathstringByAppendingPathComponent:@"path"];
// 文件管理器对象
NSFileManager * fileManager =[NSFileManager defaultManager];// 获取单例对象(NSFileManager是一个单例类)
// 根据路径创建文件夹
NSDictionary * fileData =@{@"creataTime":@"2015-9-10"};
[fileManagercreateDirectoryAtPath:directroyPath withIntermediateDirectories:YESattributes:fileData error:nil];
NSLog(@"%@",directroyPath);
NSString * dicPath1 = [directroyPathstringByAppendingPathComponent:@"path.txt"];
// 次方法适用于数据是NSData的类型的
[fileManagercreateFileAtPath:dicPath1 contents:data attributes:fileData];
// 删除指定文件
// 判断给指定文件路径是否真实存在
BOOL flag = [fileManagerfileExistsAtPath:dicPath1];
if (flag == YES) {
[fileManager removeItemAtPath:dicPath1error:nil];
}
#pragma mark---NSUserDefaults
//注意:NSUserDefaults(数据量大的时候不往这里存储,一般只存储简单对象类型)与应用程序无关的东西千万不能往这里放,一般只存储用户名和密码
NSUserDefaults * defaults = [NSUserDefaultsstandardUserDefaults];// 获取单例对象(NSUserDefaults是一个单例类)
// 这个不是立即存储,一般可能有短暂延迟,当系统有空就存储
[defaults setValue:@"lanou"forKey:@"userName"];
[defaults setObject:@"王正羽"forKey:@"name"];
// 立即同步到文件中
[defaults synchronize];// 提高优先级
NSString * name = [defaultsvalueForKey:@"userName"];
NSString * name1 = [defaults valueForKey:@"name"];
}
————————集合视图
1.创建一个UICollectionViewCell .h声明属性
@property(nonatomic,retain)UIImageView * imageView;// 图片
2.UICollectionViewCell .m重写父的方法
-(instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
self.imageView =[[UIImageView alloc] initWithFrame:CGRectMake(0, 30,CGRectGetWidth(self.frame), CGRectGetHeight(self.frame)-30)];
[self.contentViewaddSubview:_imageView];
[_imageView release];
} return self;}
3.在ViewController 声明 UICollectionView 属性
4.创建布局方式对象
UICollectionViewFlowLayout * layout =[[UICollectionViewFlowLayout alloc] init];
layout.sectionInset =UIEdgeInsetsMake(30, 20, 10, 20);使用layout.进行属性设置
5.创建集合视图,并指定集合布局方式
self.collectionView =[[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
6.遵守协议UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout
7.设置代理 _collectionView.delegate = self; _collectionView.dataSource = self;
8.添加视图 [self.view addSubview:_collectionView];
9.设置数据源(实现协议中方法) 分区,分区item,cell显示及其他
10.cell显示
MyCell * cell =[collectionView dequeueReusableCellWithReuseIdentifier:@"cell"forIndexPath:indexPath];
NSLog(@"%@",NSStringFromCGRect(cell.contentView.frame));
cell.imageView.image = [UIImageimageNamed:@"7.jpg"];
————————SHA1加密
NSMutableDictionary *dic =[[NSMutableDictionary alloc] initWithObjectsAndKeys:@"上海",@"city",@"美食",@"category",@"30",@"limit",@"1",@"page",nil];
// 进行加密
NSMutableDictionary * dict =[SignatrueEncryption encryptedParamsWithBaseParams:dic];// 加密过程
// 拼接网址
NSString * sign = dict[@"sign"];
#warning mark---网址中不能含有汉字,如果有汉字,将其转码
NSString * city = [dict[@"city"]stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString * urlString = [NSStringstringWithFormat:@"http://api.dianping.com/v1/deal/find_deals?appkey=42960815&sign=%@&city=%@&category=%@&limit=30&page=1",sign,city,category];
NSURL * url = [NSURLURLWithString:urlString];
NSData * data = [NSDatadataWithContentsOfURL:url];
if (data != nil) {
NSMutableDictionary * dic =[NSJSONSerialization JSONObjectWithData:data options:NSUTF8StringEncodingerror:nil];
NSMutableArray * array =dic[@"deals"];
self.cityArray = [NSMutableArrayarray];
for (NSMutableDictionary * dict inarray) {
NSMutableArray * array1 =dict[@"businesses"];
for (NSMutableDictionary *dic1 in array1) {
Model * model = [Model new];
[modelsetValuesForKeysWithDictionary:dic1];
[_cityArray addObject:model];}} }后面就是cell显示
————————GCD 串行队列
使用系统自带的mainQueue(主队列) dispatch_queue_t queue = dispatch_get_main_queue();// 获得主队列
自己创建 dispatch_queue_tqueue = dispatch_queue_create("com.lanou3g.myQueue",DISPATCH_QUEUE_SERIAL);
采用异步方式向队列中添加任务 dispatch_async(queue, ^{
NSLog(@"任务1,是否是主线程:%d,%@",[NSThread isMainThread],[NSThread currentThread]);
});
释放dispatch_release(queue);
————————GCD 并行队列
①:使用系统提供的:全局队列(globalQueue) dispatch_queue_t queue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
②:使用自己创建的并行队列
dispatch_queue_t queue =dispatch_queue_create("com.lanou3g.myQueue",DISPATCH_QUEUE_CONCURRENT);
————————GCD 将图片显示在相框
- (IBAction)showImage:(UIButton*)sender {
// 获取全局队列(并列队列)
dispatch_queue_t queue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
__block ViewController * VC = self;
dispatch_async(queue, ^{
#warning mark ---这里面的事情由子线程去做
NSString * imageURL =@"http://b.hiphotos.baidu.com/zhidao/pic/item/10dfa9ec8a1363275b21075f938fa0ec09fac78a.jpg";
NSURL * url = [NSURLURLWithString:imageURL];
NSData * data = [NSDatadataWithContentsOfURL:url];
UIImage * image = [UIImage imageWithData:data];
// 获取主线程,使用GCD ,要先获得主队列,因为只有主队列中,才有主线程
// 获取主队列
dispatch_queue_t mainQueue =dispatch_get_main_queue();
dispatch_async(mainQueue, ^{
// 当前是主线程执行的任务
VC.showImageView.image = image;
NSLog(@"%d",[NSThreadisMainThread]);
});
});
}
—————————通知
// 1⃣️通知中心 获得通知中心这个单例对象
NSNotificationCenter * notficationCenter =[NSNotificationCenter defaultCenter];
// 2⃣️ 注册通知 [notficationCenter addObserver:selfselector:@selector(PayMoney:) name:@"findCow" object:nil];
// 3⃣️ 执行响应后的方法
-(void)PayMoney:(NSNotification *)notification{
UIColor * color =notification.userInfo[@"color"];
self.view.backgroundColor = color;
}
// // 4⃣️ 向通知中心发送响应 这一步是响应放执行的
// 1.获取通知中心对象
NSNotificationCenter * center =[NSNotificationCenter defaultCenter];
// 2.参数的作用就是传值 第一个参数:响应通知名 第二个参数:还牛的人 第三个参数表示:传到通知中心的值
NSDictionary * value =@{@"cowName":@"小黄",@"color":[UIColor yellowColor]};
[centerpostNotificationName:@"findCow" object:self userInfo:value];
// ��️ 销毁通知中心 在程序结束后销毁
[[NSNotificationCenter defaultCenter]removeObserver:self name:@"findCow" object:nil];