1、block高级
实现回调
block是匿名函数,能够实现函数回调功能。
用于页面之间通信,同时可以进行传值。
Block内存问题
定义属性接收block,必须使用copy修饰。retain无效,即retain和assign会造成野指针问题。
block在某个方法中定义时存储在栈区,在另一个类中使用需要进行copy,存储在堆区。
当不使用block时需要销毁,Block_Release()
循环引用
在block实现部分,不能直接使用实例变量、self调用属性,因为block会造成self引用计数加1,最终导致循环引用问题。
使用__block解决循环引用的问题。
总结
使用block实现回调功能,清晰,简化代码
声明block的属性时,需要使用copy。在dealloc中要使用对应的Block_release()
在block实现部分,不要直接使用self、实例变量、属性,会造成循环引用
2. UITabBarController
详见UI15代码
#import "MainTabBarController.h"
#import "FirstViewController.h"
#import "SecondViewController.h"
#import "ThirdViewController.h"
@interface MainTabBarController ()
@end
@implementation MainTabBarController
- (void)viewDidLoad {
[super viewDidLoad];
// 初始化将要添加的视图控制器
FirstViewController *firstVC = [[FirstViewController alloc] init];
SecondViewController *secondVC = [[SecondViewController alloc] init];
ThirdViewController *thirdVC = [[ThirdViewController alloc] init];
UINavigationController *firstNaVC = [[UINavigationController alloc] initWithRootViewController:firstVC];
UINavigationController *secondNaVC = [[UINavigationController alloc] initWithRootViewController:secondVC];
UINavigationController *thirdNaVC = [[UINavigationController alloc] initWithRootViewController:thirdVC];
// 添加子视图控制器
/*
addChildViewController:是UIViewController的方法,可以把任何一个视图控制器指定为容器
*/
[self addChildViewController:firstNaVC];
// [self.view addSubview:firstNaVC.view];
[self addChildViewController:secondNaVC];
[self addChildViewController:thirdNaVC];
// 设置标题
firstNaVC.tabBarItem.title = @"消息";
secondNaVC.tabBarItem.title = @"联系人";
thirdNaVC.tabBarItem.title = @"动态";
// 为tabBar设置图片(30*30) 注意关闭图片渲染
firstNaVC.tabBarItem.image = [[UIImage imageNamed:@"01.jpg"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
thirdNaVC.tabBarItem.image = [[UIImage imageNamed:@"04.jpg"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
secondNaVC.tabBarItem.image = [[UIImage imageNamed:@"02.jpg"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}