在这里分析上两篇实现中一些技巧的东西:
1.随处可以见的善用set方法置数据:
在ChartCell中定义了ChartCellFrame这个属性:
@property (nonatomic, strong)ChartCellFrame* cellFrame;
- (void)setCellFrame:(ChartCellFrame *)cellFrame
{
_cellFrame = cellFrame;
ChartMessage* chartMessage = cellFrame.chartMessage;
self.icon.frame = cellFrame.iconRect;
self.icon.image = [UIImage imageNamed:(NSString*)chartMessage.icon];
self.chartView.chartMessage = chartMessage;
self.chartView.frame = cellFrame.chartViewRect;
[self setBackGroundImageViewImage:self.chartView from:@"chatfrom_bg_normal.png" to:@"chatto_bg_normal.png"];
self.chartView.contentLabel.text = chartMessage.content;
}
但在setCellFrame这个方法里面却同时设置了别的东西,这里是对ChartMessage的设置。
同理:ChartCellFrame类里面定义的ChartMessage也是这样操作。
总结:
优点:这样做的好处是大大减少了初始化initWith的时候的方法设置的复杂程度,我们可以在init初始化的时候常常会顺带地设置很多相关的东西,这样的setFrame可以归类地设置相关的东西。
缺点:很多属性的设置被分散化,碎片化,这样的话,增加我们如何设置才是最优的方法的难度。本质上和init里面设置是一样的效果。
2.善用代理,并且“嵌套”使用
我们来看看这里使用到的两个委托:
ChartContentViewDelegate 的定义和实现:
#import <Foundation/Foundation.h>
@class ChartContentView, ChartMessage;
@protocol ChartContentViewDelegate <NSObject>
- (void)chartContentViewLongPress:(ChartContentView *)chartView content:(NSString *)content;
- (void)chartContentViewTapPress:(ChartContentView *)chartView content:(NSString *)content;
@end
@interface ChartCell ()<ChartContentViewDelegate>
@end
- (void)chartContentViewTapPress:(ChartContentView *)chartView content:(NSString *)content
{
if ([self.delegate respondsToSelector:@selector(chartCell:tapContent:)])
{
[self.delegate chartCell:self tapContent:content];
}
}
ChartCellDelegate的定义和实现:
#import <UIKit/UIKit.h>
@class ChartCell;
@protocol ChartCellDelegate <NSObject>
- (void)chartCell:(ChartCell *)chartCell tapContent:(NSString *)content;
@end
视图控制器里面实现的委托方法:
#pragma mark - ChartCellDelegate
- (void)chartCell:(ChartCell *)chartCell tapContent:(NSString *)content
{
NSLog(@" Nest Delegate .");
}
这样隔一层的实现使得面相对象的层次感,类的功能任务所属更加明确!
3.面相对象的类的划分明确:
MVC这个模式在这个实现中非常明晰,用上一节的图可以很清楚地表现出来: