iOS CTMediator

401 阅读2分钟

随着公司的业务越来越多,项目也越来越大,项目耦合也越来越严重。传统的MVC模式已经解决不了问题,组件化势在必行。组件化可以使你的项目变成一个个组件,除了依赖于公共组件,其他每个组件都可以和新的组件组成新的app,这样大大减少了工作量。本文主要采用的是CTMediator的组件化方案。CTMediator源码链接

CTMediator采用的是target-action的方式,通过runtime的反射机制来获取类和方法。

demo链接组件化

首先创建模块分类CTMediator+live.h

.m中的实现

特别注意Target_后的模块名和constkXMMediatorTargetLive的值一定要绝对一致

#import "CTMediator+live.h"

// target 模块名称,对应Action类名后缀,一定要一样!Target_Live.h

NSString*constkXMMediatorTargetLive =@"Live";

NSString*constkXMMediatorActionNativeFetchLiveHomePageController =@"NativeFetchLiveHomePageController";

NSString*constkXMMediatorActionNativeFetchLiveChannelController =@"NativeFetchLiveChannelController";

@implementation CTMediator (live)

  • (UIViewController *)XMMediator_viewControllerForLiveHomePage {

    UIViewController *viewController = [self performTarget:kXMMediatorTargetLive

                                                    action:kXMMediatorActionNativeFetchLiveHomePageController

                                                    params:nil

                                         shouldCacheTarget:NO];

    if([viewControllerisKindOfClass:[UIViewControllerclass]])

        {

        returnviewController;

        }

    else

        {

        return[[UIViewControlleralloc]init];

        }

}

  • (UIViewController *)XMMediator_viewControllerForLiveWatchPage:(NSDictionary *)params {

    UIViewController *viewController = [self performTarget:kXMMediatorTargetLive

                                                    action:kXMMediatorActionNativeFetchLiveChannelController

                                                    params:params

                                         shouldCacheTarget:NO];

    if([viewControllerisKindOfClass:[UIViewControllerclass]])

        {

        returnviewController;

        }

    else

        {

        return[[UIViewControlleralloc]init];

        }

}

@end

然后创建Target_Live.h

.m中实现

  注意如果你的参数不用这么复杂可以不用下面的私有方法,跟官方一样简单就好,根据自己的实际需求来

#import "Target_Live.h"

#import 

@implementation Target_Live

  • (UIViewController *)Action_NativeFetchLiveHomePageController:(NSDictionary *)params {

    return [self viewControllerForString:@"XMLiveHomePageController" params:params];

}

  • (UIViewController *)Action_NativeFetchLiveChannelController:(NSDictionary *)params {

    return [self viewControllerForString:@"XMLiveChannelController" params:params];

}

#pragma mark- private

/// 给vc赋值参数

  • (UIViewController *)viewControllerForString:(NSString *)vcStr params:(NSDictionary *)params {

    Classcls =NSClassFromString(vcStr);

    UIViewController*temInstance = [[clsalloc]init];

    if([temInstanceisKindOfClass:[UIViewControllerclass]]) {// 严谨判断 是viewcontroller or子类

        if(params) {

            [selfupdateParam:paramsforInstance:temInstance];

        }

        returntemInstance;

    }

    return nil;

}

/// 给对象赋值参数

  • (void)updateParam:(NSDictionary*)paramsforInstance:(NSObject*)obj {

    NSDictionary*objProperties = [selfpropertyFroObj:obj];

    for(NSString*keyinparams.allKeys) {

        if([objPropertiesvalueForKey:key]) {

            [objsetValue:params[key]forKey:key];

        }else{

            NSLog(@"XMSport Router Warning( Live sectoin) : 跳转对象没有该属性 %@ %@", obj, key);

        }

    }

}

/// 获取obj的所有属性

  • (NSDictionary *)propertyFroObj:(NSObject *)obj {

    NSMutableDictionary *propertiesDic = [NSMutableDictionary dictionary];

    unsignedintpropertyCount =0;

    objc_property_t*properties =class_copyPropertyList([objclass], &propertyCount);

    for(intidx =0; idx

        objc_property_tproperty = properties[idx];

        NSString *propertyName = [[NSString alloc] initWithCString:property_getName(property) encoding:NSUTF8StringEncoding];

        [propertiesDicsetValue:@1forKey:propertyName];

    }

    free(properties);

    return[propertiesDiccopy];

}

@end

最后调用

UIViewController*viewController =  [[CTMediator sharedInstance] XMMediator_viewControllerForLiveHomePage];

 [self.navigationController pushViewController:viewController animated:YES]; CTMediator的问题在于你如果只是做一个小的项目,完全用不着组件化,小项目只会增加更多的工作量,另外组件化也可以搭配mvc和MVVM等其他设计模式使用。

另一个问题在于传递参数的时候,有硬编码。这就需要开发人员有较高的技艺,需要细心,不然容易出现找不到值的问题,甚至产生运行时错误。