(四)封装和优化的一些规范

十一.字典转模型

用字典存放数据的坏处:
字典的key有可能写错。

因此常用模型来存储数据。

创建一个模型类。注意字符串的@property用copy代替strong(copy用到NSString)。

weak一般用于UI控件,assign用于基本数据类型。

这样只需要检查字典转换为模型时的key是否正确。

控制器直接访问模型内部的属性,会造成高度耦合,应该将模型进一步封装,应该将字典转模型的内容封装在模型里。

写一个构造方法,initWithDict:dict
构造方法返回id类型。

注意命名规范可以减少同事间的沟通成本。
AppData类,注意类方法以类名开头,并且在避免死循环的情况下多用self。

- (id)initWithDict : (NSDictionary *)dict{

    ifself = [super init] ){

        self.name = dict[@"name"];

        self.icon = dict[@"icon"];

    }

    return self;

}


+ (id)appWithDict : (NSDictionary *)dict{

    return [[self allocinitWithDict:dict];

}


自从IOS7开始,建议不使用id(万能指针),id的缺点是不能判别类型是否正确。推荐将id替换为instancetype。


instancetype只能用于返回值类型。


十二.xib的使用


storyboard 描述软件的所有界面,重量级。
xib 描述局部界面,轻量级。

xib的创建:empty User Interface就是xib

xib的获取,使用bundle,由于可能有多个view,所以返回数组:

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是固定的。


十三.封装

还是以应用管理为例。

1.使用viewWithTag后面加数字不太可靠。
2.控制器对xib内部了解的太多。

解决方案:
创建一个类继承UIView作为xib的控制器。
将控件作为类的成员变量。

注意这时候获取到的UIView应该是相应控制器名称类型。

技巧:为了让@property生成的内容可以被类外访问,把property写在.h文件中,即可直接获取。

@interface AppView : UIView


@property (weaknonatomicIBOutlet UIImageView *iconView;

@property (weaknonatomicIBOutlet 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 (nonatomicstrongAppData *app;


@end


@interface AppView ()


@property (weaknonatomicIBOutlet UIImageView *iconView;

@property (weaknonatomicIBOutlet 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属性是透明度。



posted on 2015-02-04 21:11  张大大123  阅读(200)  评论(0编辑  收藏  举报

导航