赞
踩
在iOS的UI界面中,我们会经常遇见传值的问题,今天学习了一种新的传值方法——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];
}
效果图如下:
我们使用的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 不然会形成循环引用
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。