经过这三个月的学习java
我发现java的框架真的很好
比如 连接数据库的dao层,spring框架可直接利用接口和配置文件创建一个对象,而这个对象实现了接口的函数.
我思考了一些时间,真正动手却是昨天,经过两天一夜的奋战,终于整理出来一份很垃圾的小demo.
这个思想呢,到底是叫IOC还是aop,我不知道,我只知道,给定一个未实现的接口(objective-c中叫协议)就能实现这些方法的声明.
创建一个接口(oc叫协议)
=======================================
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@protocol JJHttpMapper <NSObject>
@required
- (void)test_url_login_parameter:(NSDictionary *)parameter
body:(NSDictionary*_Nullable)body
configBlock:(JJHTTPMapperFailureBlock_Nonnull)configBlock
successBlock:(JJHTTPMapperFailureBlock_Nonnull)successBlock
failureBlock:(JJHTTPMapperFailureBlock_Nonnull)failureBlock;
@end
NS_ASSUME_NONNULL_END
=======================================
利用JJHttpMappingManager创建一个遵循JJHttpMapper协议的类.
=======================================
id <JJHttpMapper>mapper = [JJHttpMappingManager createMapper_protocol:@protocol(JJHttpMapper)
plistName:@"JJHttpMapper.plist"];
[mappertest_url_login_parameter:@{} body:@{} configBlock:^(NSError * _Nonnull error) {
}successBlock:^(NSError*_Nonnullerror) {
}failureBlock:^(NSError*_Nonnullerror) {
}];
=======================================
以上为使用方法.
=======================================
=======================================
具体实现:
首先创建一个类
JJMapperImpl.h
=======================================
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface JJMapperImpl : NSObject
@property (nonatomic ,strong)NSString *config_path;
//这个应该将网络请求的manager返回,可配置一些头文件等
typedefvoid(^JJHTTPMapperConfigBlock)(NSString*_Nonnullmessage);
typedefvoid(^JJHTTPMapperSuccessBlock)(NSString*_Nonnullmessage,id_NullableresponseObject);
typedefvoid(^JJHTTPMapperFailureBlock)(NSError*_Nonnullerror);
- (void)impl_urlSession:(NSString*_Nonnull)method
:(NSString*_Nonnull)urlString
:(NSDictionary*_Nullable)parameter
:(NSDictionary*_Nullable)body
:(JJHTTPMapperFailureBlock_Nonnull)configBlock
:(JJHTTPMapperFailureBlock_Nonnull)successBlock
:(JJHTTPMapperFailureBlock_Nonnull)failureBlock;
@end
NS_ASSUME_NONNULL_END
=======================================
JJMapperImpl.m
=======================================
#import <objc/message.h>
#import "JJMapperImpl.h"
@implementation JJMapperImpl
- (void)impl_urlSession:(NSString*_Nonnull)method
:(NSString*_Nonnull)urlString
:(NSDictionary*_Nullable)parameter
:(NSDictionary * _Nullable )body
:(JJHTTPMapperFailureBlock _Nonnull )configBlock
:(JJHTTPMapperFailureBlock _Nonnull )successBlock
:(JJHTTPMapperFailureBlock_Nonnull)failureBlock{
}
@end
=======================================
JJHttpMappingManager.h
=======================================
#import <Foundation/Foundation.h>
#import "JJMapperImpl.h"
NS_ASSUME_NONNULL_BEGIN
@interface JJHttpMappingManager : NSObject
+ (JJMapperImpl*)createMapper_protocol:(Protocol*)protocolplistName:(NSString*)plistName;
@end
NS_ASSUME_NONNULL_END
=======================================
JJHttpMappingManager.m
=======================================
// Copyright © 2020 jjyangjian. All rights reserved.
//
#import "JJHttpMappingManager.h"
#import <objc/runtime.h>
#import <objc/message.h>
#import "JJHttpMapper.h"
@implementation JJHttpMappingManager
+ (JJMapperImpl*)createMapper_protocol:(Protocol*)protocolplistName:(NSString*)plistName{
// Class SubMapperClass = objc_allocateClassPair([JJMapperImpl class], "SubMapperClass", 0);
// Protocol *protocol = objc_allocateProtocol((char *)[dict[@"mapperName"] UTF8String]);
ClassJJMapperImplClass =JJMapperImpl.class;
// JJMapperImpl *mapperImpl = JJMapperImpl.new;
class_addProtocol(JJMapperImplClass, protocol);
unsignedintmethodCount =0;
structobjc_method_description*method_description_list =protocol_copyMethodDescriptionList(protocol,true,true, &methodCount);
for(inti =0; i < methodCount ; i ++){
structobjc_method_descriptiondescription = method_description_list[i];
NSLog(@"index:%d name:%@ type:%@",i,NSStringFromSelector(description.name),[NSString stringWithUTF8String:description.types]);
class_addMethod(JJMapperImplClass, description.name, (IMP)static_urlSession, description.types);
}
free(method_description_list);
JJMapperImpl*mapper = [[JJMapperImplClassalloc]init];
NSLog(@"%d",[mapperconformsToProtocol:protocol]);
mapper.config_path= [[NSBundlemainBundle]
pathForResource:[NSString stringWithFormat:@"%@",plistName]
ofType:nil];
return mapper;
}
static void static_urlSession(id self,
SELsel,
NSDictionary*_Nullableparameter,
NSDictionary*_Nullablebody,
JJHTTPMapperFailureBlock_NonnullconfigBlock,
JJHTTPMapperFailureBlock_NonnullsuccessBlock,
JJHTTPMapperFailureBlock_NonnullfailureBlock)
{
// 获取类中指定名称实例成员变量的信息
Ivarivar =class_getInstanceVariable([selfclass],"test");
// 获取整个成员变量列表
// Ivar * class_copyIvarList ( Class cls, unsigned intint * outCount );
// 获取类中指定名称实例成员变量的信息
// Ivar class_getInstanceVariable ( Class cls, const charchar *name );
// 获取类成员变量的信息
// Ivar class_getClassVariable ( Class cls, const charchar *name );
// 返回名为test的ivar变量的值
idobj =object_getIvar(self, ivar);
NSLog(@"%@",obj);
// NSLog(@"mapper_imp:参数:%@",parameter);
NSLog(@"ClassName:%@",NSStringFromClass([selfclass]));
NSString *selName = NSStringFromSelector(sel);
NSArray *arr = [selName componentsSeparatedByString:@"_"];
NSMutableString *urlSuffix = NSMutableString.new;
//接口后缀处理完毕
for(inti =0; i < arr.count-1; i ++) {
[urlSuffixappendString:@"/"];
[urlSuffixappendString:arr[i]];
}
NSDictionary *configDictionary =[NSDictionary dictionaryWithContentsOfFile:((JJMapperImpl *)self).config_path];
NSArray*list = configDictionary[@"list"];
NSString*method =@"GET";
for(inti =0; i < list.count; i ++) {
if([urlSuffixisEqualToString:list[i][@"suffix"]]) {
method = list[i][@"method"];
}
}
[((JJMapperImpl *)self) impl_urlSession:method
:[NSStringstringWithFormat:@"www.baidu.com%@",urlSuffix]
:parameter
:body
:configBlock
:successBlock
:failureBlock];
}
@end
=======================================
以上就是小demo
但事实上,直接利用最简单的方式也能完成,我发现这份代码基本没什么用🙄就当对runtime的一个研究吧
网友评论