(四)封装和优化的一些规范
- (id)initWithDict : (NSDictionary *)dict{
if( self = [super init] ){
self.name = dict[@"name"];
self.icon = dict[@"icon"];
}
return self;
}
+ (id)appWithDict : (NSDictionary *)dict{
return [[self alloc] initWithDict:dict];
}
自从IOS7开始,建议不使用id(万能指针),id的缺点是不能判别类型是否正确。推荐将id替换为instancetype。
instancetype只能用于返回值类型。
十二.xib的使用
NSBundle *bundle = [NSBundle mainBundle];
NSArray *objs = [bundle loadNibNamed:@"AppView" owner:nil options:nil];
防止数组加载失败时越界:
UIView *appView = [objs lastObject];
获取xib中的子控件:
1.appView.subviews数组,从0开始排
2.使用tag绑定,viewWithTag方法。
注意tag不要用0开始,一般是10 20 30这样写。
nib和xib:面向开发人员的叫xib,安装到手机上会转为nib(加密过)。
使用xib:当发现某一块view是固定的。
@interface AppView : UIView
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
@end
appView.iconView.image = [UIImage imageNamed:appInfo.icon];
appView.nameLabel.text = appInfo.name;
这样避免了使用tag。
步骤:新建xib->构建xib->给xib添加控制器->通过bundle获取xib(为xib控制器类型)->通过xib控制器修改xib内容。
缺点是这样的话控制器知道xib控制器有可直接访问的内部属性,因此这时候应该将组件放在.m的封装声明内。
改进方案:
将xib控制器的内容写在.m内进行私有封装,
然后在.h中要求传入的为模型,然后重写get方法。get方法注意固定写法,第一句为_xxx = xxx;
具体实现为:
@class AppData;
@interface AppView : UIView
@property (nonatomic, strong) AppData *app;
@end
@interface AppView ()
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
@end
@implementation AppView
- (void)setApp:(AppData *)app{
_app = app; //注意,固定写法。
self.iconView.image = [UIImage imageNamed:app.icon];
self.nameLabel.text = app.name;
}
@end
这时还不是最佳方案,因为控制器内还有使用bundle获取xib的部分,控制器知道xib的获取。
应该屏蔽创建xib的过程。
具体方法是在AppView内增加一个类方法,直接返回一个xib的view。
+ (instancetype)appView{
NSBundle *bundle = [NSBundle mainBundle];
NSArray *objs = [bundle loadNibNamed:@"AppView" owner:nil options:nil];
return [objs lastObject];
}
通过类方法来生成appView:
AppView *appView = [AppView appView];
进一步封装:AppView直接在创建时传入模型:
+ (instancetype)appViewWithApp:(AppData *)app{
AppView *appView = [self appView];
appView.app = app;
return appView;
}
AppView *appView = [AppView appViewWithApp:self.apps[index]];
封装的总结:
使用xib封装一个自定义view的步骤:
1.新建一个xib和与之对应的控制器(继承UIView)。
2.绑定xib与控制器,连线绑定属性(放置在.m的私有声明内)。
3.另外定义一个模型类,作为xib参数的集合。
4.在xib的.h控制器中提供模型属性,可供设置。
5.重写模型属性的set方法,拆开模型设置到xib的具体子控件中去。
6.提供一个类方法,用于创建一个xib。(屏蔽创建的bundle获取过程)。
这就是基础的MVC。
M最轻松,C最繁琐,V处于中间层。
C负责加载模型数据(重写get方法,懒加载)。
一个V对应一个M,V拿到M后进行显示。
补充:
1.xib的加载过程:根据设置转为代码,最后都放到一个数组内。
2.xib与storyboard的对比
xib和storyboard都是使用Interface Builder来编辑。
Xcode3之前 Interface Builder 和 Xcode 是独立的。
xib是轻量级的,描述局部界面,storyboard描述全部页面。
alpha属性是透明度。