Block传值
在iOS的UI界面中,我们会经常遇见传值的问题,今天学习了一种新的传值方法——Block传值,Block传值和协议传值一样都是反向传值的方法,一般用于后一个界面向前一个界面传值,但Block传值在使用起来比协议传值简单。
Block传值的基本步骤
下面举了一个应用Block传值的例子:
在A界面设置了一个UILabel,在B界面设置了一个UITextField,需要将第二个界面输入框的值传回到UILabel中。
1.在第二个界面中定义一个代码块,随后定义一个Block属性,这里的关键字要使用copy。
#import <UIKit/UIKit.h>
// 定义一个代码块,后面为block传的值的类型,可以是多个参数
typedef void(^BToAblock)(NSString *string);
NS_ASSUME_NONNULL_BEGIN
@interface SecondViewController : UIViewController
@property (nonatomic, strong) UITextField* bTextField;
// 定义一个block属性
@property (nonatomic, copy) BToAblock block;
@end
2.在B界面的.m文件设置一个按钮,给其添加按钮事件,事件内容即为实现Block传值的代码,并撤销当前视图:
#import "SecondViewController.h"
@interface SecondViewController ()
@end
@implementation SecondViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor systemTealColor];
_bTextField = [[UITextField alloc] init];
_bTextField.frame = CGRectMake(100, 300, 200, 50);
_bTextField.layer.borderColor = [UIColor whiteColor].CGColor;
_bTextField.layer.borderWidth = 1;
[self.view addSubview:_bTextField];
UIButton* ansButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[ansButton setTitle:@"返回" forState:UIControlStateNormal];
ansButton.frame = CGRectMake(100, 400, 200, 50);
[ansButton addTarget:self action:@selector(pressChange:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:ansButton];
}
- (void)pressChange:(UIButton*)sender {
// 将需要传出的值作为代码块的参数
_block(self.bTextField.text);
// 退出当前视图
[self dismissViewControllerAnimated:YES completion:nil];
}
3.在A界面中,设置一个按钮事件,推出B视图的同时,完成Block传值的赋值:
- (void) pressPush {
SecondViewController* secondViewController = [[SecondViewController alloc] init];
secondViewController.modalPresentationStyle = UIModalPresentationFullScreen;
// block传值的实现部分。
[secondViewController setBlock:^(NSString *string) {
self.aLabel.text = string;
}];
[self presentViewController:secondViewController animated:YES completion:nil];
}
效果图
效果图如下:
lazy loading(懒加载)
简介
我们使用的iOS设备的内存都是有限的,如果我们的程序内包含大量的资源,启动时一次性加载,可能会使手机的内存不够。所以在书写程序时我们可以采取懒加载的方法。
懒加载:又称延迟加载,顾名思义,延缓资源的加载,即在需要的时候才加载,在程序启动的时候不加载资源,而是当运行时需要其时才加载,这是苹果官方提倡的一种做法,苹果公司在很多地方都用到了懒加载,比如说控制器的View创建。
懒加载的实现
那么该如何实现懒加载呢?
实现懒加载的步骤很简单,只需要重写get
方法即可.
下面举一个例子:实现一个UILabel控件的懒加载
1.首先定义控件,其属性关键字比如为strong
@property (nonatomic, strong) UILabel* textLabel;
2.接下来重写控件的getter
,将要实现的逻辑放在getter
中.
- (UILabel*) textLabel {
// 判断UILabel是否存在,不存在时进行实例化
if (!_textLabel) {
self.textLabel = [[UILabel alloc] init];
self.textLabel.font = [UIFont systemFontOfSize:20];
self.textLabel.text = @"懒加载";
self.textLabel.frame = CGRectMake(100, 100, 100, 40);
self.textLabel.textAlignment = NSTextAlignmentCenter;
}
return _textLabel;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
// 这里只是一个指针不会占用内存
[self.view addSubview:self.textLabel];
}
懒加载的优点
1.使用懒加载可以将代码按照模块进行封装,提高了类的灵活度。
2.可以在一段时间内节省内存的使用,如果需要视图,调用getter方法显示视图,不需要时为空视图。
3.不用讲代码都写入viewDidLoad方法中,代码的可读性更强。
4.每个控件的getter方法中分别负责各自的实例化处理,代码彼此之间的独立性强。
懒加载的注意
注意指针的循环引用问题
if (_textLabel == nil) 不可以写成 if (self.textLabel == nil) ,不然会造成循环引用指针
return _textLabel 不可以写成return self.textLabel 不然会形成循环引用