IOS常用封装总结


//封装总结
如何封装?
1.确定变化点
  *.数据变化点(数据模型), 重写set
  *.通信(代理, block)
2.确定一个容器(UIView)
3.逻辑搭建
  *.UI 搭建
  *.响应 UI 的逻辑
//1>登录模块的封装(新建类继承自UIVIew)
1.代理的作用
 *封装变化点
 *解决类与类之间的强耦合性
 *可以在类之间进行数据传递
2.什么情况下使用代理
 *有一系列的变化点,能够让用户清晰的知道到底有哪些变化点被封装起来了
//登录封装变化点:需要用代理来传递密码和用户名
3.外部(.h)
*提供一个类方法用于外界获取到自己(xib加载)
*提供代理方法,传递数据给控制器
4.内部(.m)
*定义子控件(UITestField,UIButton)
*定义按钮事件(实现代理方法,传递数据)

//2>控制器
1.初始化数据源(重写get方法 实现懒加载)
2.加载并初始化视图,建立父子关系
2.传递数据源


//3>封装ScrollView广告轮播(新建类继承自UIView)
1.外部(.h)
*提供一个类方法。用于外界获取到自己
*提供一个代理方法,当点击scrollView上的方法时,控制器获取此按钮事件时执行相应的操作
- (void)adsViewDidSelected:(GPAdsView *)adsView andImage:(NSString *)image andIndex:(NSInteger)index;
@property(nonatomic,assign)id<GPAdsViewDelegate> delegate;
*提供一个NSArray属性,存储数据,用于传递scrollView需要的数据
2.内部(.m)
*定义控件属性(pageControl,Timer,ScrollView等)
*实现类方法,返回一个UIView对像
*在initFrame对象方法中,实例化控件,设置一些控件的基本属性(此时不建议设置大小,大小应有父类获取到并赋值)并保存,添加到父视图中
/* 在初始化子视图时最好是先创建一个新视图,再赋值给自己的属性视图
 */
注:在视图示例化时最终调用的是initframe方法,init ->initFrame
*在willMoveToSuPerView设置主视图的frame及其属性,并给子控件设置大小
//子控件参考父控件设置 Frame 值
*重写数据的set方法,给scrollView添加子视图,更新本视图的所有数据
//1.设置依赖于数据的一些属性
//2.计算ScrollView的 ContentSize
//3.给 ScrollView 添加子控件
*添加NSTimer,实现自动播放功能,在ScrollDidScroll方法中,更新pageControl的当前页
// 创建:NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(autoScroll) userInfo:nil repeats:YES];
// 将一个 timer 对象加入到最主要的事件循环中
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
// 1.计算当前应该显示到的具体页数
// 2.更新scrollView的偏移量
 在scrollViewWillBeginDragging方法中销毁Timer,在scrollViewDidEndDragging方法中重新创建Timer(NSTimer一旦停止就会被销毁,所以得重写创建,为了让广告不受其他操作的影响,应该在创建Timer对象时给它提供多线程处理,加入到最主要的事件循环中[[NSRunLoop currentRunLoop]addTimer:self.timer forMode:NSRunLoopCommonModes];)

4> 封装UITableView(新建xib,继承自UIView)
1.外部(.h)
*提供一个类方法,用于外界获取到自己
*提供一个数组属性(控制器数据源数组数据),存储外界传来的数据(用于定义行数,以及cell数据)
2.内部(.m)
*实现类方法,返回一个UITableView(从xib获得)
//return [[[NSBundle mainBundle] loadNibNamed:@"GPContentView" owner:nil options:nil] lastObject]
*继承UITableView 数据源方法,实现numberOfRowsInSection方法及其cellForRowAtIndexPath方法(返回的是自定义的cell对象,自定义cell对象提供模型数据,将控制器传来的数据源赋给cell的模型对象)
*重写数据源的set方法,将外界传递过来的数据保存,并且一定要更新tableView对象数据([self.tableView reloadData])
*在awakeFromNib方法中给tableView添加子控件(如:广告轮播添加到头视图)
// 只要当前对象是从 xib 文件中加载来的,就会自动调用awakeFromNib方法

5>封装cell(新建xib,继承自UITableViewCell)
// 考虑cell复用机制
//去内存池中取可重用的 cell
//1.如果有给你返回一个可重用的 cell
//2.如果没有,自动创建一个返回给你用
* 对于频繁加载的 xib 文件,不要使用loadNibNamed
//注册 直接使用类名作为唯一标识
+ (id)subjectCellWithTableView:(UITableView *)tableView
{
  // 1.注册 直接使用类名作为唯一标识
  NSString * Identifier = NSStringFromClass([self class]);
  // 2.创建UINib对象
  UINib * nib = [UINib nibWithNibName:Identifier bundle:nil];
 // 3.使用注册机制, xib 文件上不需要再去加上重用标识
 [tableView registerNib:nib forCellReuseIdentifier:Identifier];
 // 4.复用返回
 return [tableView dequeueReusableCellWithIdentifier:Identifier];
}

1.外部(.h)
*提供一个类方法,用于外界获取到自己
+ (id)subjectCellWithTableView:(UITableView *)tableView;
*提供一个数组数据(模型数据),存储模型数据用于给Cell属性赋值
*提供一个带有参数的类方法,用于从缓冲池中取的Cell数据
2.内部(.m)
*定义子控件
*实现类方法,返回一个UITableViewCell对象(从xib中获得)
*实现带参数的类方法(从传过来的tableView缓冲池中取出有相同ID的Cell数据,返回一个Cell)
*重写数据的set方法,给Cell的属性赋值

6>模型封装(模型数据,继承自NSobject)

*将需要的数据属性抽象成模型属性(一般是NSDictionary,将字典里的key值和模型属性一一对应)
*提供一个类方法和一个对象方法(因为操作习惯,会不自觉的使用类方法初始化,所以在实例化时最好提供一个类方法),都带字典参数
*实现类方法和对象方法创建模型( [self setValuesForKeysWithDictionary:dict];)
*对于嵌套模型,应当在重写init方法是再将子模型模型封装
- (id)initWithDict:(NSDictionary *)dict
{
    if (self = [super init])
    {
        [self setValuesForKeysWithDictionary:dict];
        NSMutableArray * objs = [NSMutableArray array];
        for (NSDictionary * dic in self.friends)
        {
            GPFriend * friend = [GPFriend friendWithDict:dic];
            [objs addObject:friend];
        }
        //更新一下自己的 friends 属性
        _friends = objs;
    }
    return self;
}
*当有字典属性和系统关键字冲突时调用forUndefinedKey方法解决
/**
 *  没有定义属性
 */
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
    if ([key isEqualToString:@"id"]) {
        self.iD = value;
    }
}













原文地址:https://www.cnblogs.com/3WWanXiang/p/4894535.html