iOS开发 项目总结

作者: CurrentUserID | 来源:发表于2020-10-10 16:30 被阅读0次

1、UIButton点击事件用block代替

添加UIButton分类,在分类中添加如下代码
在.h文件中添加

typedef void (^ClickButtonBlock)(UIButton *button);

/**
 将Block点击属性与点击事件进行关联
 
 @param aEvent UIControlEvents
 @param block 点击事件
 */
- (void)handleClickEvent:(UIControlEvents) aEvent usingBlock:(ClickButtonBlock)block;

在.m文件中添加

#import <objc/runtime.h>

static char *overViewKey;

- (void)handleClickEvent:(UIControlEvents)aEvent usingBlock:(ClickButtonBlock)block {
    objc_setAssociatedObject(self, &overViewKey, block, OBJC_ASSOCIATION_COPY_NONATOMIC);
    // 给button增加点击事件
    [self addTarget:self action:@selector(buttonClicked:) forControlEvents:aEvent];
}

- (void)buttonClicked:(UIButton *)sender {
    ClickButtonBlock clickedBlock = objc_getAssociatedObject(self, &overViewKey);
    // 如果block存在则调用Blcok
    if (clickedBlock != nil) {
        clickedBlock(sender);
    }
}

用到了runtime的objc_setAssociatedObject(关联)
函数

void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)

参数说明

 id object                     :表示关联者,是一个对象,变量名理所当然也是object
 const void *key               :获取被关联者的索引key
 id value                      :被关联者,这里是一个block
 objc_AssociationPolicy policy :关联时采用的协议,有assign,retain,copy等协议

调用

[collectionBtn handleClickEvent:UIControlEventTouchUpInside usingBlock:^(UIButton *button) {
        //点击事件
}];

好处
1、在写项目时候不用写一堆全局变量来传参,block可以捕获局部变量到block内部直接用
2、不用写[self addTarget:self action:@selector(想函数名想半天:) forControlEvents:UIControlEventTouchUpInside ];这行代码

有需要给view添加点击事件的需求该方法也适用,需要简单改改代码
还可以给view添加个分类实现渐变色,相关文章:
(https://www.jianshu.com/p/e7c9e94e165b)
(https://www.jianshu.com/p/9f350164c766)

2.与webview交互

//再声明webView时添加代理(WKScriptMessageHandler)
[self.webView.configuration.userContentController addScriptMessageHandler:self name:@"kScriptMessageHandlerWithname"];
//实现协议方法
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
    if (message.body){
        if ([message.name isEqualToString:@"kScriptMessageHandlerWithname"]){
                //Code...
        }
    }
}
//移除代理
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"kScriptMessageHandlerWithname"];
}

3.在控制台中打印中文

在iOS开发中,我们调试接口时最多的就是用NSLog 或者是打断点来po 数据,然而NSLog 输出的数据中,中文是UFT-8格式显示的,所以为了解决这个问题,今天给大家推荐一个非常好的方法,主要思路就是利用objc/runtime运行时机制 来替换掉系统的控制台输出方法,然后将utf-8格式的字符转换成中文格式。

一般情况下,我们在使用NSLog 和 %@ 输出某个对象时,就会调用这个对象的 description 方法,它的返回值就是 NSString 字符串类型,所以 description 默认实现返回的格式是 <类名: 对象的内存地址>,

在必要情况下,我们需要重写description方法以达到改变输出结果目的,覆盖description方法的默认实现。重写完description方法后,再调用NSLog(@”%@”,p)时输出结果不再是<类名: 内存地址>,而是返回的字符串。

注意:千万不要在 description 方法中同时使用 %@ 和 self,如果这样使用了,那么最终会造成程序死循环,原因是因为:如果使用了%@和self,代表要调用self的description方法,最终就是循环调用description方法。
方法:创建一个类
.h中什么都不用写
.m中如下

#import <objc/runtime.h>

static inline void zxp_swizzleSelector(Class class, SEL originalSelector, SEL swizzledSelector) {
    Method originalMethod = class_getInstanceMethod(class, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
    if (class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))) {
        class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
    } else {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}

@implementation NSString (ZXPUnicode)

- (NSString *)stringByReplaceUnicode {
    NSMutableString *convertedString = [self mutableCopy];
    [convertedString replaceOccurrencesOfString:@"\\U"
                                     withString:@"\\u"
                                        options:0
                                          range:NSMakeRange(0, convertedString.length)];
    
    CFStringRef transform = CFSTR("Any-Hex/Java");
    CFStringTransform((__bridge CFMutableStringRef)convertedString, NULL, transform, YES);
    return convertedString;
}

@end

@implementation NSArray (ZXPUnicode)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];
        zxp_swizzleSelector(class, @selector(description), @selector(zxp_description));
        zxp_swizzleSelector(class, @selector(descriptionWithLocale:), @selector(zxp_descriptionWithLocale:));
        zxp_swizzleSelector(class, @selector(descriptionWithLocale:indent:), @selector(zxp_descriptionWithLocale:indent:));
    });
}

- (NSString *)zxp_description {
    return [[self zxp_description] stringByReplaceUnicode];
}

- (NSString *)zxp_descriptionWithLocale:(nullable id)locale {
    return [[self zxp_descriptionWithLocale:locale] stringByReplaceUnicode];
}

- (NSString *)zxp_descriptionWithLocale:(nullable id)locale indent:(NSUInteger)level {
    return [[self zxp_descriptionWithLocale:locale indent:level] stringByReplaceUnicode];
}

@end

NSDictionary、NSSet同理

相关文章

网友评论

    本文标题:iOS开发 项目总结

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