[New learn] 设计模式思考

时间:2023-03-10 04:27:56
[New learn] 设计模式思考

本文是对上文[New learn] 设计模式的思考总结

1.大框架

无论应用使用多少种设计模式和技巧,此模式都是应用的大框架。下图为本项目的基本架构图:

[New learn] 设计模式思考

1.上图中大框架为经典的MVC模式。

2.Controller将View于Model分割开来。

3.Model不应该出现任何View的引用。同样的View中应该不会有任何Model的引用,哪怕是仅仅的import都不行。

4.View的数据需要将Model的数据转变成通用的基本书库结构,如字典,字符串等等。

5.View的数据请求需要向controller去取得,是通过委托(协议)

6.Controller内对于数据库,网络或者本地数据的取得封装经统一的API中,此API内部进行复杂的迭代,外部暴露给controller的只是统一的API即可。

7.对于运行时候的动态条用,可以通过NSNotificationCenter以观察者订阅消息来通信,同样不能跨Model和View。

2.小细节

a.父view删除全部子view:

    [scroller.subviews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        [obj removeFromSuperview];
    }];

b.KVO: 需要在销毁时候取消观察

[coverImage addObserver:self forKeyPath: context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"image"])
    {
        [indicator stopAnimating];
    }
}
- (void)dealloc
{
    [coverImage removeObserver:self forKeyPath:@"image"];
}

c.通知:需要在销毁时候取消观察

        [[NSNotificationCenter defaultCenter] postNotificationName:@"BLDownloadImageNotification"
                                                            object:self
                                                          userInfo:@{@"imageView":coverImage, @"coverUrl":albumCover}];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downloadImage:) name:@"BLDownloadImageNotification" object:nil];
- (void)downloadImage:(NSNotification*)notification
{

    UIImageView *imageView = notification.userInfo[@"imageView"];
    NSString *coverUrl = notification.userInfo[@"coverUrl"];

    imageView.image = [persistencyManager getImage:[coverUrl lastPathComponent]];

    if (imageView.image == nil)
    {

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{
            UIImage *image = [httpClient downloadImage:coverUrl];

            dispatch_sync(dispatch_get_main_queue(), ^{
                imageView.image = image;
                [persistencyManager saveImage:image filename:[coverUrl lastPathComponent]];
            });
        });
    }
}
- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

d.单例写法:

+ (LibraryAPI*)sharedInstance
{
    // 1 创建一个静态属性,属性将成为类属性,用于记录当前实例
    static LibraryAPI *_sharedInstance = nil;

    // 2 创建一次性执行标记位,确保第三步骤只会被执行一次
    static dispatch_once_t oncePredicate;

    // 3 使用GCD方法来执行初始化方法,此方法将根据oncePredicate来执行,值执行一次
    dispatch_once(&oncePredicate, ^{
        _sharedInstance = [[LibraryAPI alloc] init];
    });
    return _sharedInstance;
}

e.配置变量保存和读取:

- (void)saveCurrentState
{
    // When the user leaves the app and then comes back again, he wants it to be in the exact same state
    // he left it. In order to do this we need to save the currently displayed album.
    // Since it's only one piece of information we can use NSUserDefaults.
    [[NSUserDefaults standardUserDefaults] setInteger:currentAlbumIndex forKey:@"currentAlbumIndex"];

    [[LibraryAPI sharedInstance] saveAlbums];
}

- (void)loadPreviousState
{
    currentAlbumIndex = [[NSUserDefaults standardUserDefaults] integerForKey:@"currentAlbumIndex"];
    [self showDataForAlbumAtIndex:currentAlbumIndex];
}

f.图片读取:

- (void)saveImage:(UIImage*)image filename:(NSString*)filename
{
    filename = [NSHomeDirectory() stringByAppendingFormat:@"/Documents/%@", filename];
    NSData *data = UIImagePNGRepresentation(image);
    [data writeToFile:filename atomically:YES];
}

- (UIImage*)getImage:(NSString*)filename
{
    filename = [NSHomeDirectory() stringByAppendingFormat:@"/Documents/%@", filename];
    NSData *data = [NSData dataWithContentsOfFile:filename];
    return [UIImage imageWithData:data];
}