Viewer源码阅读心得5——总结

版权所有, 转载请著明出处,保留链接。
Viewer源码阅读心得5——总结

##架构概括
Viewer 主要分三个模块, 分别是关系数据模型CoreData, 存储模块(thumb图片的获取), UI模块(初始化和用户交互),三个模块分别在前几章都已经详细分析过。一般来说一个APP = 数据 + UI, 存储模块在这里也归为数据的部分,其实其是工具模块。关系数据模型通过类CoreDataManager单例架构CoreData体系, 有对象DocumentFolder和ReaderDocument;存储模块通过类ReaderThumbCache单例作为接口, 其中ReaderThumbRequest是与外界通信的参数。UI模块中主要分两大部分, 一部分是DocumentFolder和ReaderDocument对象的呈现和交互, 是通过LibraryViewController来实现的,还一部分是ReaderDocument, 即PDF文档的阅读, 是通过ReaderViewController控制器来实现的。那么这三者是怎么交互的呢?

    UI模块
    /    \
   /      \
  /        \
存储模块    关系数据模型CoreData

显然在UI模块的初始化和用户交互过程中, 当需要thumb的时候, 则调用ReaderThumbCache类单例的方法, 来获取thumb, 他们之间通信的参数是ReaderThumbRequest,是一个输入输出参数, 输入的是要获取thumb的信息, 输出的ReaderThumbView,即包含thumb的视图。当UI模块中需要呈现和交互DocumentFolder和ReaderDocument对象时, 会通过CoreData体系来增删改查相应的对象。

以上讲的都是UI模块初始化或交互时, 怎么调用其他两个模块, 通过对象直接调用,那么当关系数据模型变化时, 怎么去通知UI模块呢, 难道也是直接调用, 显然是通过通知中心NSNotificationCenter, 即UI模块订阅通知, 把自己在通知中心中注册为观察者, 而关系数据模型模块, 当实体发生变化时候, 向通知信息发出消息, 并携带必要的消息信息。例如在CoreData模块中:

DocumentFolderDeletedNotification        document删除通知         LibraryDocumentsView观察者     folderWasDeleted
DocumentFolderRenamedNotification        document重命名           LibraryDocumentsView观察者     folderWasRenamed
....


DocumentsUpdateOpenNotification            document打开通知         LibraryViewController观察者    openNewDocument
                                                                LibraryDocumentsView观察者     openedNewDocument

可见, NSNotificationCenter大大减少了对象间的耦合, 那么在什么情况下使用NSNotificationCenter呢?我觉得在是不同的模块间, 对象间不能通过很自然组合关系来进行直接的调用, 而这时通过消息中心, 就能达到解耦的作用, 并且使程序架构的设计更加的合理。

##代码规范
对外可见部分在头文件中声明,即.h文件, 声明依次:

类的前向性声明
枚举类型的声明
协议的声明
类接口的声明,
类属性对外接口
类方法的声明
常量的声明

例如DocumentFolder的头文件如下:

@class ReaderDocument;
typedef NS_ENUM(NSInteger, DocumentFolderType)
{
    DocumentFolderTypeUser = 0,
    DocumentFolderTypeDefault = 1,
    DocumentFolderTypeRecent = 2
};

@interface DocumentFolder : NSManagedObject

@property (nonatomic, strong, readwrite) NSString *name;
@property (nonatomic, strong, readwrite) NSNumber *type;
@property (nonatomic, strong, readwrite) NSSet *documents;
@property (nonatomic, assign, readwrite) BOOL isChecked;

+ (NSArray *)allInMOC:(NSManagedObjectContext *)inMOC;
+ (BOOL)existsInMOC:(NSManagedObjectContext *)inMOC name:(NSString *)string;
+ (BOOL)existsInMOC:(NSManagedObjectContext *)inMOC type:(DocumentFolderType)kind;
+ (DocumentFolder *)folderInMOC:(NSManagedObjectContext *)inMOC type:(DocumentFolderType)kind;
+ (DocumentFolder *)insertInMOC:(NSManagedObjectContext *)inMOC name:(NSString *)string type:(DocumentFolderType)kind;
+ (void)renameInMOC:(NSManagedObjectContext *)inMOC objectID:(NSManagedObjectID *)objectID name:(NSString *)string;
+ (void)deleteInMOC:(NSManagedObjectContext *)inMOC objectID:(NSManagedObjectID *)objectID;

extern NSString *const DocumentFolderAddedNotification;
extern NSString *const DocumentFolderRenamedNotification;
extern NSString *const DocumentFolderDeletedNotification;
extern NSString *const DocumentFolderNotificationObjectID;
extern NSString *const DocumentFoldersDeletedNotification;

在类的实现文件中, 即.m文件中, 实现依次:

常量定义
类的实现定义:对外不可见字段
类的属性的重新声明对内使用
类方法的实现
内部调用方法的实现
对外调用方法的实现
父类方法的重载实现
各种委托协议方法的实现

这里没有包括了类的扩展实现部分, 具体的实例就不展现了, 如果感兴趣, 可以去研究下源, 总之, Viewer的代码结构还是非常漂亮的, 值得我学习。

至此, viewer的源代码阅读结束,大概花了一个月的时间, 从读懂源代码到把这些心得写出来。Viewer涉及了CoreData, 图片存储, UIScrollView等知识点, 对我提升比较大, 这段时间花下去还是比较值得的。在这里, 感慨: 做一个专注的人真难!

版权所有, 转载请著明出处,保留链接。