高能

封装YYCategory的实践2018

2018-07-31  本文已影响211人  勇往直前888

背景简介

根据YY作者的自述文章最近一段时间的工作整理整个YYKit是由一系列文章组成。这个导入YYKit整体感觉有点乱,最后还是根据需要,分模块导入,分别封装一下后,自己再重新组织一下,换个名字,比如KJTKit之类的。经过几天的封装,已经差不多了,还剩下YYCategory,这是小工具,有些很有用,并且类别的使用方式是Object-C特有的,也很普遍。剩下几个工程中暂时还没有涉及,等以后用到了再说。

image.png

封装NSDate

网络来的日期,一般是毫秒数,通过这个创建NSDate对象,有现成API,只是不要忘记将毫秒转化成秒,要除以1000
+ (instancetype)dateWithTimeIntervalSince1970:(NSTimeInterval)secs;

// 字符串转日期
+ (nullable NSDate *)kjtDateWithString:(NSString *)dateString format:(NSString *)format {
    return [NSDate dateWithString:dateString format:format];
}

// 日期转字符串
- (nullable NSString *)kjtStringWithFormat:(NSString *)format {
    return [self stringWithFormat:format];
}
// 相邻几天,昨天就给-1,明天给1
- (nullable NSDate *)kjtDateByAddingDays:(NSInteger)days {
    return [self kjtDateByAddingDays:days];
}

封装NSObject

// 添加观察者
- (void)kjtAddBlockForKeyPath:(NSString*)keyPath
                        block:(void (^)(id _Nonnull obj, id _Nonnull oldVal, id _Nonnull newVal))block {
    [self addObserverBlockForKeyPath:keyPath block:block];
}

// 移除所有观察者,防止内存泄漏
- (void)kjtRemoveAllBlocks {
    [self removeObserverBlocks];
}

- (void)removeObserverBlocksForKeyPath:(NSString*)keyPath;是故意不提供的,防止内存泄漏

// 交换实例方法
+ (BOOL)kjtSwizzleInstanceMethod:(SEL)originalSel with:(SEL)newSel {
    return [[self class] swizzleInstanceMethod:originalSel with:newSel];
}

// 交换静态类方法
+ (BOOL)kjtSwizzleClassMethod:(SEL)originalSel with:(SEL)newSel {
    return [[self class] swizzleClassMethod:originalSel with:newSel];
}
// 设置指针型关联变量
- (void)kjtSetAssociateValue:(nullable id)value withKey:(void *)key {
    [self setAssociateValue:value withKey:key];
}

// 设置数值型关联变量
- (void)kjtSetAssociateWeakValue:(nullable id)value withKey:(void *)key {
    [self setAssociateWeakValue:value withKey:key];
}

// 读取关联变量
- (nullable id)kjtGetAssociatedValueForKey:(void *)key {
    return [self getAssociatedValueForKey:key];
}

// 移除所有的关联变量,防止内存泄漏
- (void)kjtRemoveAssociatedValues {
    [self removeAssociatedValues];
}

封装NSString

// md5
- (nullable NSString *)kjtMd5String {
    return [self md5String];
}
// base64
- (nullable NSString *)kjtBase64EncodedString {
    return [self base64EncodedString];
}
// url编码
- (NSString *)kjtUrlEncodeString {
    return [self stringByURLEncode];
}

// url解码
- (NSString *)kjtUrlDecodeString {
    return [self stringByURLDecode];
}
// 标签关键字替换为&字符
- (NSString *)kjtEscapingHTMLString {
    return [self stringByEscapingHTML];
}
// 去掉首尾空格
- (NSString *)kjtTrimString {
    return [self stringByTrim];
}
// 判空
- (BOOL)kjtIsEmpty {
    return ![self isNotBlank];
}
// 判断是否包含字符集; - (BOOL)containsString:(NSString *)string; iOS8已经提供,这里不重复
- (BOOL)kjtContainsCharacterSet:(NSCharacterSet *)set {
    return [self containsCharacterSet:set];
}
// json解码
- (id)kjtDecodeJson {
    return [self jsonValueDecoded];
}
// 从文件读内容
+ (NSString *)kjtFileStringNamed:(NSString *)name {
    return [self stringNamed:name];
}

封装UIApplication

属性类型的接口并不是很友好,全部改成函数形式的。
另外,实例方法要通过[UIApplication sharedApplication]访问,不是很方便,所以都改成类的静态方法。

// 文档和cache的路径
+ (NSURL *)kjtDocumentsURL {
    return [UIApplication sharedApplication].documentsURL;
}

+ (NSString *)kjtDocumentsPath {
    return [UIApplication sharedApplication].documentsPath;
}

+ (NSURL *)kjtCachesURL {
    return [UIApplication sharedApplication].cachesURL;
}

+ (NSString *)kjtCachesPath {
    return [UIApplication sharedApplication].cachesPath;
}
// 应用标识符
+ (NSString *)kjtAppBundleName {
    return [UIApplication sharedApplication].appBundleName;
}

+ (NSString *)kjtAppBundleID {
    return [UIApplication sharedApplication].appBundleID;
}
// 版本号
+ (NSString *)kjtAppVersion {
    return [UIApplication sharedApplication].appVersion;
}

+ (NSString *)kjtAppBuildVersion {
    return [UIApplication sharedApplication].appBuildVersion;
}
// 是否盗版,这里改了下名字,是否从苹果市场安装
+ (BOOL)kjtIsFromAppstore {
    return ![UIApplication sharedApplication].isPirated;
}

NSData封装

这个和NSString有相似之处,比如加解密这一块。不过又有很大不同,NSData是机器码,01类型的数据流,而NSString是可以写进文档,打印出来看的可见字符。这两者的差异还是很大的,平时使用的时候要注意一下。NSData不可打印,打印出来,就成了description,是01组成的字符了。

// md5
- (NSString *)kjtMd5String {
    return [self md5String];
}

- (NSData *)kjtMd5Data {
    return [self md5Data];
}
// 转字符串
- (nullable NSString *)kjtUtf8String {
    return [self utf8String];
}
// 与16进制字符串互转
- (nullable NSString *)kjtHexString {
    return [self hexString];
}

+ (nullable NSData *)kjtDataWithHexString:(NSString *)hexString {
    return [NSData dataWithHexString:hexString];
}
// base64 字符串糊状
- (nullable NSString *)kjtBase64EncodedString {
    return [self base64EncodedString];
}

+ (nullable NSData *)kjtDataWithBase64EncodedString:(NSString *)base64EncodedString {
    return [NSData dataWithBase64EncodedString:base64EncodedString];
}
// json 解码
- (id)kjtDecodeJson {
    return [self jsonValueDecoded];
}
// 从文件中读
+ (nullable NSData *)kjtFileDataNamed:(NSString *)name {
    return [NSData dataNamed:name];
}

封装UIColor

主要是和16进制字符串的互转

// 与16进制字符串互转
+ (nullable UIColor *)kjtColorWithHexString:(NSString *)hexStr {
    return [UIColor colorWithHexString:hexStr];
}

- (nullable NSString *)kjtHexString {
    return [self hexString];
}

- (nullable NSString *)kjtHexStringWithAlpha {
    return [self hexStringWithAlpha];
}

封装UIDevice

这些主要是硬件信息,是属性形式的接口,访问需要[UIDevice currentDevice],不是很方便,改成类静态接口。

// 系统版本号
+ (double)kjtSystemVersion {
    return [UIDevice systemVersion];
}
+ (BOOL)kjtIsPad {
    return [UIDevice currentDevice].isPad;
}

+ (BOOL)kjtIsSimulator {
    return [UIDevice currentDevice].isSimulator;
}

+ (BOOL)kjtIsJailbroken {
    return [UIDevice currentDevice].isJailbroken;
}

+ (BOOL)kjtCanMakePhoneCalls {
    return [UIDevice currentDevice].canMakePhoneCalls;
}

+ (NSString *)kjtMachineModel {
    return [UIDevice currentDevice].machineModel;
}

+ (NSString *)kjtMachineModelName {
    return [UIDevice currentDevice].machineModelName;
}
// ip 地址
+ (NSString *)kjtIpAddressWIFI {
    return [UIDevice currentDevice].ipAddressWIFI;
}

+ (NSString *)kjtIpAddressCell {
    return [UIDevice currentDevice].ipAddressCell;
}
// 唯一标识符
+ (NSString *)kjtIdfvUuidString {
    return [[UIDevice currentDevice].identifierForVendor UUIDString];
}

封装NSNotificationCenter

@interface NSNotification : NSObject <NSCopying, NSCoding>

@property (readonly, copy) NSNotificationName name;
@property (nullable, readonly, retain) id object;
@property (nullable, readonly, copy) NSDictionary *userInfo;

- (instancetype)initWithName:(NSNotificationName)name object:(nullable id)object userInfo:(nullable NSDictionary *)userInfo API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)) NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;

@end
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(test) name:@"test" object:nil];
+ (void)kjtPostNotificationOnMainThreadWithName:(NSString *)name
                                      object:(nullable id)object
                                    userInfo:(nullable NSDictionary *)userInfo {
    [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:name object:object userInfo:userInfo];
}

参考文章

YYCategories

文档地址

上一篇下一篇

猜你喜欢

热点阅读