Small knowledge, big challenge! This paper is participating in theEssentials for programmers”Creative activities

Why componentization

  1. Decoupling between modules
  2. Module reuse
  3. Improve team collaboration and development efficiency
  4. Unit testing

The principle of componentization

  • Only the top can depend on the bottom
  • The project’s common code resources sink
  • Horizontal dependencies are best sunk

CocoaPods manages componentization layering

  1. cdGo to the test directory, pod lib create TSHomeModuleNext, select the platform, language, and so on to configure as needed.

  1. When the project is created, it will automatically open and find that there is nothing in the project and the Pods are empty.

  2. The code we need to create is the EXample project in TSHomeModule. The layer code we need to write is in the ReplaceMe box below.

  1. Add code that needs to be layered

5. Go back to Example abovepod install“, the file you just added is now brought in.

  1. Error found because some third party is not imported. Add configuration dependencies to Pod file for Example project

  1. againpod install

  1. Run an error, found that there are still their own classification extension is not added. Continue with this example

  1. Add categories where you need to rely on using them

CocoaPods manages stomp – componentized file resource loading

If there are still image resources that need to be loaded, it’s natural to put them in Assets above Classes

But if the resource is in here, then we need to specify the resource path when we use the [**UIImage imageNamed:] method in Example. We also need to add a configuration message here

NSString *bundlePath = [[NSBundle bundleForClass:[self class]].resourcePath stringByAppendingPathComponent:@"/TSModuleTest.bundle"];
NSBundle *resoure_bundle = [NSBundle bundleWithPath: bundlePath];
self.imageView.image = [UIImage imageNamed:@"share_wechat" inBundle:resoure_bundle compatibleWithTraitCollection:nil];
Copy the code

Other resources such as JSON files and XIBs are treated this way.

Componentized CTMediator is decoupled

Target-action: If the outer layer wants to access ModuleA

  1. ModuleAisCTMediatorIf I want to jump to A, I will rewrite the intermediate management level in ACTMediatorThe method ofperformTarget:action:params:This method, because this method can be customized according to the module
  2. Overridden targets are eventually locatedTarget_AI’m responding in hereaction

Componentized BeeHive decoupling

Protocol oriented, rewrites UIAppDelegate for the system. Go to the main function and find the custom TestAppDeledate inheriting from the BHAppDelegate

  1. 1 To multi – distribution problem
- (void)applicationWillResignActive:(UIApplication *)application
{
    [[BHModuleManager sharedManager] triggerEvent:BHMWillResignActiveEvent];
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [[BHModuleManager sharedManager] triggerEvent:BHMDidEnterBackgroundEvent];
}
Copy the code
  1. Component communication – static injectionregisterLocalServices
[[BeeHive shareInstance] setContext:[BHContext shareInstance]];
Copy the code

What you’re actually loading is a plist fileserviceIs the agreement,implIs a VC

NSString *protocolKey = [dict objectForKey:@"service"];
NSString *protocolImplClass = [dict objectForKey:@"impl"];
Copy the code

  1. Component communication – Dynamically injected classes**registerService:implClass:**
  // HomeServiceProtocol & homeVc
    // When the binding was created:
    id<HomeServiceProtocol> homeVc = [[BeeHive shareInstance] createService:@protocol(HomeServiceProtocol)];
Copy the code

Class implClass = [self.service implClass :service];

@BeeHiveService(HomeServiceProtocol,BHViewController)
#define BeeHiveService(servicename,impl) \
class BeeHive; char * k##servicename##_service BeeHiveDATA(BeehiveServices) = "{ \""#servicename"\" : \""#impl"\"}";
#define BeeHiveDATA(sectname) __attribute((used, section("__DATA,"#sectname"")))
Copy the code

This macro is going to look like this

class BeeHive; 
char * kHomeServiceProtoco_service __attribute((used, section("__DATA,"BeehiveServices""=)))"{ \""HomeServiceProtocol"\" : \""BHViewController"\"}";

Copy the code

__DATA is written directly to the section and then read in the _dyLD_register_func_for_add_image callback, which can be seen in the dyld source code of the OC underlying application loading process. _dyLD_register_func_FOR_add_image registers the specified function to be called when a new image (bundle or dynamic shared library) is added for each image of the current program

Finally, after both dynamic and static binding, the members of the array are: