美文网首页iOS设计模式JC专题
IOS 面向接口编程 Objection基本原理

IOS 面向接口编程 Objection基本原理

作者: Aliyunyun | 来源:发表于2016-04-21 16:39 被阅读1335次

    1、Objection 基本使用

    例子:

    1、Enginer

    .h
    @interface Enginer : NSObject
    @end
    
    .m
    @implementation Enginer
    objection_register(@"Enginer")
    @end
    

    2、Car

     .h
     @interface Car : NSObject
     @property(nonatomic, strong) Enginer *mEnginer;
     @end
    .m
     @implementation Car
     objection_requires(@"mEnginer")
     @end
    

    3、ViewController

    .h
    @property (nonatomic, strong) Car *mCar;
    .m
    - (void)viewDidLoad
    {
       [super viewDidLoad];
       self.mCar = [[JSObjection createInjector]getObject:[Car class]];
    }
    

    在ViewController里面获取的Car 的实体,并且,Car里面的Enginer也会自动创建。

    Objection原理解析

    Objection 通过传入class,通过class name 字符串化后创建一个JSObjectionInjectorEntry,并且以class name为key 保存到字典中,在获取的时候获取这个injectorEntry,获取到class 后,创建对象。

    注册: objection_register(@"类名")
    声明需要注入的参数: objection_requires(@"对象名")
    注入: [[JSObjection createInjector]getObject:[Car class]]

    ojbection_register()
    
    #definde objection_register(value)
    +(void)initialize{
         if(self == [value class]){
            [[JSObjection registerClass:[value class] scope: JSObjectionScopeNormal];
      }    
    }
    

    这个是到底做了什么呢?

    
    static NSMutableDictionary *gObjectionContext
    
    +(void)registerClass:(Class)theClass scope:(JSObjectionScope)scope
    
    //核心代码
    [gObjectionContext 
     setObject:[JSObjectionInjectorEntry entryWithClass: theClass scope:scope] 
     forKey: NSStringFromClass(theClass) ];
    

    从上面可以看出来,实际上就是将一个JSObjectionInjectorEntry ,保存到一个以类名对应的一个字典里面。

    那这个JSObjectionInjectorEntry 是什么东西呢?

    typedef enum{
      JSObjectionScopeNone = -1,
      JSObjectionScopeNormal ,
     JSObjecitonScopeSingleton
    }
    
    @interface JSObjectionInjectorEntry : JSObjectionEntry
      @property (nonatomic, readonly) Class classEntry;
    @end
    
    @interface JSObjectionInjectorEntry ()
          JSObjectionScope _lifeCycle;
          id _storageCache;
    @end
    
    @implement
       + (id)entryWithClass: (Class) theClass scope:(JSObjectionScope)theLifeCycle{
    return [[JSObjectionInjectorEntry alloc]initWithClass:theClass lifeCycle:thelifeCycle];
    }
    
    - (instancetype)initWithClass:(Class)theClass lifeCycle:(JSObjectionScope)theLifeCycle{
       _lifeCycle = thelifeCycle;
       _classEntry = theClass;
      _storageCache = nil;
    }
    @end
    
    

    从上面的代码可以看出来,JSObjectionInjectorEntry 保存了
    1、class _ckassEntry
    2、JSObjectionScope lifeCycle

    从上面可以看出来,注册就是把class name 和 JSObjectionInjectiorEnry用字典保存到gObjectionContext ,Entry保存的了Class 和 lifeCycle.

    2、 objection_requires()获取参数

    这里就一个方法,会返回一个需要注入的参数列表

    #define objection_requires(args...)
         +(NSSet *)objectionRequires{
           NSSet *requirements = [NSSet setWithObjects: args, nil];
           return JSObjectionUtils.buildDependenciesForClass(self, requirements);
      }
    
    static NSSet *BuildDependenciesForClass(Class klass, NSSet*requirements){
       Class superClass = class_getSuperclass([klass class]);
        .....
    retrunn requirements;
    }
    

    3、注入

    通过class获取到注入器, 通过注入器获取到实例

    JSObjectionInjector
    
    -(id)getObjectWithArgs:(id)classOrProtocol,...{
         va_list va_arguments;
         va_start(va_arguments, classOrProtocol);
         id object = [self getObject:classOrProtocol arguments:va_arguments];
         va_end(va_arguments);
    return object;
    }
    
    - (id)getObject:(id)classOrProtocol name:(NSString *)name initializer:(SEL)selector arguments:(NSArray *)argumentList {
           1、通过classOrProtocol 获取key,及class name str
           2、获取injectorEntry
                 injectorEntry = [JSObjectionInjectorEntry entryWithClass scope:JSObjectionScopeNormal];
                injectorEntry.injector = self;
                _context setObject:injectorEntry forKey:key
    
          3、通过injectorEntry 获取实例对象
              [injectorEntry extractObject:argumentList  initializer:selector];
             -(id)buidlObject:(NSArray *)arguments  initializer:(SEL) initializer;
    }
    
    

    相关文章

      网友评论

        本文标题:IOS 面向接口编程 Objection基本原理

        本文链接:https://www.haomeiwen.com/subject/xectrttx.html