美文网首页
iOS开发 使用block在当前方法中获取代理方法中的参数

iOS开发 使用block在当前方法中获取代理方法中的参数

作者: 菊上一枝梅 | 来源:发表于2018-12-24 21:25 被阅读7次

    使用场景:在使用AlertView(已弃用)或UIImagePickerController这类方法时,执行操作后是需要在代理方法中实现回调的,日常应用中很多时候在调用的地方会有我们需要用到的参数,这样我们就需要用属性去记录调用方法中的参数,这样用着很是不爽,这里用两个例子来实现在当前方法中使用block来获取代理方法中的参数,使用的是runtime。

    如果runtime的方法索引不出来,那么可以尝试一下两种方法

    1.
    #import <objc/runtime.h>
    #import <objc/message.h>
    2.在"Target - Build Settings"搜索msgSend,修改"Enable Strict Checking of objc_msgSend Calls"的值为"No"
    

    AlertView的例子:

    // 定义静态常量
    static void *EOCMyAlertViewKey = "EOCMyAlertViewKey";
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"标题" message:@"内容" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"Continue", nil];
        void (^block)(NSInteger) = ^(NSInteger buttonIndex) {
            NSLog(@"%ld", buttonIndex);
        };
        objc_setAssociatedObject(alert, EOCMyAlertViewKey, block, OBJC_ASSOCIATION_COPY);
        [alert show];
    }
    
    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
        void (^block)(NSInteger) = objc_getAssociatedObject(alertView, EOCMyAlertViewKey);
        block(buttonIndex);
    }
    

    没错,上面这段代码是学的书里的,下面这段代码是用上面的方法实现的UIImagePickerController的回调。

    // 定义静态常量
    static void *PickerKey = "pickerKey";
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        UIAlertAction *cameraAction = [UIAlertAction actionWithTitle:@"拍照" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            UIImagePickerController *picker = [[UIImagePickerController alloc] init];
            picker.sourceType = UIImagePickerControllerSourceTypeCamera;
            picker.delegate = self;
            void (^block) (NSString *) = ^(NSString *imageUrlString) {
                ZHDebugLog(@"%@", imageUrlString);
            };
            objc_setAssociatedObject(picker, PickerKey, block, OBJC_ASSOCIATION_COPY);
            [self presentViewController:picker animated:YES completion:nil];
        }];
        UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
        UIAlertController *alertVc = [UIAlertController alertControllerWithTitle:@"温馨提示" message:@"系统检测到您已经更换手机或更新手机系统,需要您拍摄本人照片打卡" preferredStyle:UIAlertControllerStyleAlert];
        [alertVc addAction:cameraAction];
        [alertVc addAction:cancelAction];
        [self presentViewController:alertVc animated:YES completion:nil];
    }
    
    // UIImagePickerController代理方法
    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<UIImagePickerControllerInfoKey,id> *)info {
        [picker dismissViewControllerAnimated:YES completion:nil];
        UIImage *img = info[@"UIImagePickerControllerOriginalImage"];
        // 上传图片,获取到图片路径
        [ZHNetworkManager zh_uploadImage:img folder:@"ReplacePhoneClickInImage" success:^(NSString *imageUrlString) {
            void (^block) (NSString *) = objc_getAssociatedObject(picker, PickerKey);
            block(imageUrlString);
        }];
    }
    
    objc_setAssociatedObject(id  _Nonnull object, const void * _Nonnull key, id  _Nullable value, objc_AssociationPolicy policy)
    id object:表示关联者,是一个对象。
    const void * _Nonnull key:关联者的索引key
    id _Nullable value:被关联者,这里是一个block
    objc_AssociationPolicy policy:关联时采用的协议,有assign, retain, copy
    

    在block的回调里要注意使用weakSelf防止循环引用。

    文章不易过长,否则连我自己都不爱看了!

    相关文章

      网友评论

          本文标题:iOS开发 使用block在当前方法中获取代理方法中的参数

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