最后
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
就答题情况而言,第一问100%都可以回答正确,第二问大概只有50%正确率,第三问能回答正确的就不多了,第四问再正确就非常非常少了。其实此题并没有太多刁钻匪夷所思的用法,都是一些可能会遇到的场景,而大多数人但凡有1年到2年的工作经验都应该完全正确才对。
只能说有一些人太急躁太轻视了,希望大家通过此文了解js一些特性。
并祝愿大家在新的一年找工作面试中胆大心细,发挥出最好的水平,找到一份理想的工作。
#### 3.2 代理B–>A
1. 在B控制器头文件申明协议;
@protocol NextViewControllerDelegate
@optional
- (void)delegateSend:(NSString *)strDelegate;
@end
2. 在B控制器定义遵循协议的属性;
@property (nonatomic,assign) id delegate;
3. 在B跳回A的点击事件中调用代理方法;
-
(void)btnDelegate{
[self.delegate delegateSend:@“iOS”];
[self.navigationController popViewControllerAnimated:YES];
}
4. A遵循B的协议;
@interface ViewController ()
5. 在A跳转到B的点击事件中使A成为B的代理者;
//代理传值
-
(void)btnDelegate{
NextViewController *nextVC = [[NextViewController alloc]init];nextVC.delegate = self;
[self.navigationController pushViewController:nextVC animated:YES];
}
6. 在A控制器实现B协议中的代理方法;
//代理方法
- (void)delegateSend:(NSString *)strDelegate{
self.lblDelegate.text = strDelegate;
}
### 四、通知传值
通知传值的核心部分,就是建立好监听者与发送者在时间上的关系,即一定要先有监听者再去发送通知,掌握好了这一点就可以玩转通知传值。
#### 4.1 通知传值A–>B
1. B是消息的接收者,要在A发送消息之前先建立好监听者,这时候就需要在B中重写`init`方法来达到这个目的,然后写收到通知后的操作,最后一定要记得移除监听者,否则会造成内存泄漏;
- (instancetype)init{
if (self = [superinit]) {
//创建监听者
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeValue:) name:@“bobo” object:nil];
}
return self;
}
//通知传值
- (void)changeValue:(NSNotification *)notification{
NSDictionary * dict = notification.userInfo;
self.lblNotification.text = dict[@“key”];
}
//移除监听者
- (void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self name:@“bobo” object:nil];
}
2. 接下来就是在A的点击事件中添加发送消息即可。
// 通知传值
-
(void)btnNotification{
NextViewController *nextVC = [[NextViewController alloc]init];NSNotification *notification = [[NSNotification alloc]initWithName:@“bobo” object:nil userInfo:@{@“key”😡“shq5785”}];
// 发送通知
[[NSNotificationCenter defaultCenter] postNotification:notification];
[self.navigationController pushViewController:nextVC animated:YES];
}
#### 4.2 通知传值B–>A
1. 由B到A传值就更简单了,因为时间顺序上一定是先有A后有B,所以只要在A的`viewDidLoad`中建立一个监听者,然后实现监听事件,最后一处监听者就行
//在viewDidLoad中注册监听者
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(changeValue:) name:@“bobo2” object:nil];
//收到通知后操作
-
(void)changeValue:(NSNotification *)notification{
NSDictionary *dict = notification.userInfo;self.lblNotification.text = dict[@“key”];
}
//移除监听者
- (void)dealloc{
[[NSNotificationCenter defaultCenter]removeObserver:self name:@“bobo2” object:nil];
}
2. 在B跳转回A的时候发送通知就行了。
-
(void)btnNotification{
NSNotification * notification = [[NSNotification alloc]initWithName:@“bobo2” object:nil userInfo:@{@“key”😡“iOS”}];//发送通知
[[NSNotificationCenter defaultCenter] postNotification:notification];
[self.navigationController popViewControllerAnimated:YES];
}
### 五、单例传值
单例,就是从程序开始到程序结束不管中途怎么去实例化都只有一个实例对象,先创建一个单例(本文已Teacher类作为单例示例):
//Teacher.h
#import <Foundation/Foundation.h>
@interface Teacher :NSObject<NSCopying,NSMutableCopying>
@property (nonatomic,strong) NSString * name;
@property (nonatomic,assign) int age;
- (instancetype)shareInstance;
@end
//Teacher.m
#import “Teacher.h”
staticTeacher *teacher = nil;
@implementation Teacher
-
(instancetype)shareInstance{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
teacher = [[Teacher alloc]init];//确保对象只被初始化一次
});return teacher;
}
-
(instancetype)allocWithZone:(struct_NSZone *)zone{
if (teacher ==nil) {
teacher = [[superallocWithZone:zone]init];
}return teacher;
}
-
(instancetype)copyWithZone:(NSZone *)zone{
return teacher;
} -
(id)mutableCopyWithZone:(nullableNSZone *)zone{
return teacher;
}
@end
#### 5.1 单例传值A–>B
1. 单例传值只要在A中拿到单例对象,给对象属性赋值,都在跳转事件执行;
//单例传值
-
(void)btnInstance{
NextViewController *nextVC = [[NextViewController alloc]init];Teacher *teacher = [Teacher new];
teacher.name = @“SHQ5785”;
[self.navigationController pushViewController:nextVC animated:YES];
}
2. 在B界面拿到单例对象在给label赋值就行,在`viewDidLoad`写如下代码即可:
//单例传值
Teacher *teacher = [Teacher new];
self.lblInstance.text = teacher.name;
#### 5.2 单例传值B–>A
1. 由B界面跳回A界面也是跟A一样在跳转事件给单例对象赋值:
-
(void)btnInstance{
//单例传值
Teacher *teacher = [Teacher new];teacher.name =@“iOS”;
[self.navigationController popViewControllerAnimated:YES];
}
2. 但是A界面拿到单例值需要在`viewWillAppear`中去赋值:
-
(void)viewWillAppear:(BOOL)animated{
// 单例传值
Teacher *teacher = [Teacher new];self.lblInstance.text = teacher.name;
}
### 六、代码块传值
代码块传值很好用很方便,但是理解上需要花点功夫,接下来咱就一步一步去分析完成;
#### 6.1 代码块传值A–>B
1. 代码块由A传值到B,需要先在B的头文件中定义一个外部可用代码块属性;
@property (nonatomic,strong) void(^oneBlock)(NSString *) ;
2. 然后B给代码块赋值,但是赋值一定要在A中调用之前完成,因此也需要重写B的`init`方法
-
(instancetype)init{
if (self = [superinit]) {
//代码块传值a–>b
NextViewController *nextVC = self;_oneBlock = ^(NSString \*strBlock){ nextVC.lblBlock.text = strBlock; };
}
return self;
}
3. 在A跳转到B的点击事件中调用代码块;
//代码块传值
-
(void)btnBlock{
NextViewController * nextVC = [[NextViewController alloc]init];//a–>b
if (nextVC.oneBlock) {//调用代码块前一定要先判断代码块是否为空,调用空的代码块会直接使系统奔溃
//跳回主线程调用代码块
dispatch_async(dispatch_get_main_queue(), ^{
nextVC.oneBlock(@“SHQ5785”);
});
}[self.navigationController pushViewController:nextVC animated:YES];
}
#### 6.2 代码块传值B–>A
1. 代码块传值由B到A,也需要在B的头文件中定义一个外部可用代码块属性;
@property (nonatomic,strong) void(^myBlock)(NSString *) ;
2. 不过这时候代码块赋值操作应该在A的点击事件中进行,因为需要在B中调用代码块传送一个字符串回到A中;
//代码块传值
-
(void)btnBlock{
NextViewController *nextVC = [[NextViewController alloc] init];//b–>a
nextVC.myBlock = ^(NSString *strBlock){
self.lblBlock.text = strBlock ;
};[self.navigationController pushViewController:nextVC animated:YES];
}
3. 在B跳转回A点击事件中调用代码块完成传值。
-
(void)btnBlock{
//代码块传值b–>a
if (_myBlock) {
dispatch_async(dispatch_get_main_queue(), ^{
_myBlock(@“iOS”);
});
}[self.navigationController popViewControllerAnimated:YES];
}
#### 最后
**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/topics/618166371)**
就答题情况而言,第一问100%都可以回答正确,第二问大概只有50%正确率,第三问能回答正确的就不多了,第四问再正确就非常非常少了。其实此题并没有太多刁钻匪夷所思的用法,都是一些可能会遇到的场景,而大多数人但凡有1年到2年的工作经验都应该完全正确才对。
只能说有一些人太急躁太轻视了,希望大家通过此文了解js一些特性。
并祝愿大家在新的一年找工作面试中胆大心细,发挥出最好的水平,找到一份理想的工作。