Skip to content
This repository has been archived by the owner on Jun 2, 2018. It is now read-only.

UIEditUserWordController causes A2DynamicDelegate crash #355

Open
pengan1987 opened this issue Nov 18, 2016 · 1 comment
Open

UIEditUserWordController causes A2DynamicDelegate crash #355

pengan1987 opened this issue Nov 18, 2016 · 1 comment

Comments

@pengan1987
Copy link

pengan1987 commented Nov 18, 2016

This issue may same to #283
Procedure to reproduce this issue:

Add any Chinese/Japanese characters in an UITextField
Select the characters entered
In the popup menu, select [Learn...]
A "Text Replacement" view pops up
Click "Cancel" in top left corner
Then the app crashes

img_0604_result

The position of error:

UITextField+BlocksKit.m, line 23

//At this time, the realDelegate is an UIEditUserWordController
//which only used in asian language service
ret = [realDelegate textFieldShouldBeginEditing:textField];

A2DynamicDelegate.m, line 159

//The self.realDelegate is an pointer points to unreadable memory, then app crash
return [self.invocationsBySelectors bk_objectForSelector:selector] || class_respondsToSelector(object_getClass(self), selector) || [self.realDelegate respondsToSelector:selector];
@littleSun
Copy link

//
// UITextField+BlocksKit.m
// BlocksKit
//

#import "UITextField+BlocksKit.h"
#import "A2DynamicDelegate.h"
#import "NSObject+A2BlockDelegate.h"

#pragma mark Delegate

@interface A2DynamicUITextFieldDelegate : A2DynamicDelegate

@EnD

@implementation A2DynamicUITextFieldDelegate

  • (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
    {
    BOOL ret = YES;

    id realDelegate = self.realDelegate;

    if (realDelegate && [realDelegate isKindOfClass:NSClassFromString(@"UIEditUserWordController")]) {
    return ret;
    }

    if (realDelegate && [realDelegate respondsToSelector:@selector(textFieldShouldBeginEditing:)])
    ret = [realDelegate textFieldShouldBeginEditing:textField];
    BOOL (^block)(UITextField *) = [self blockImplementationForMethod:_cmd];
    if (block)
    ret &= block(textField);
    return ret;
    }

  • (void)textFieldDidBeginEditing:(UITextField *)textField
    {
    id realDelegate = self.realDelegate;

    if (realDelegate && [realDelegate isKindOfClass:NSClassFromString(@"UIEditUserWordController")]) {
    return;
    }

    if (realDelegate && [realDelegate respondsToSelector:@selector(textFieldDidBeginEditing:)])
    [realDelegate textFieldDidBeginEditing:textField];
    void (^block)(UITextField *) = [self blockImplementationForMethod:_cmd];
    if (block)
    block(textField);
    }

  • (BOOL)textFieldShouldEndEditing:(UITextField *)textField
    {
    BOOL ret = YES;
    id realDelegate = self.realDelegate;

    if (realDelegate && [realDelegate isKindOfClass:NSClassFromString(@"UIEditUserWordController")]) {
    return ret;
    }

    if (realDelegate && [realDelegate respondsToSelector:@selector(textFieldShouldEndEditing:)])
    ret = [realDelegate textFieldShouldEndEditing:textField];
    BOOL (^block)(UITextField *) = [self blockImplementationForMethod:_cmd];
    if (block)
    ret &= block(textField);
    return ret;
    }

  • (void)textFieldDidEndEditing:(UITextField *)textField
    {
    id realDelegate = self.realDelegate;

    if (realDelegate && [realDelegate isKindOfClass:NSClassFromString(@"UIEditUserWordController")]) {
    return;
    }

    if (realDelegate && [realDelegate respondsToSelector:@selector(textFieldDidEndEditing:)])
    [realDelegate textFieldDidEndEditing:textField];
    void (^block)(UITextField *) = [self blockImplementationForMethod:_cmd];
    if (block)
    block(textField);
    }

  • (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
    {
    BOOL ret = YES;
    id realDelegate = self.realDelegate;

    if (realDelegate && [realDelegate isKindOfClass:NSClassFromString(@"UIEditUserWordController")]) {
    return ret;
    }

    if (realDelegate && [realDelegate respondsToSelector:@selector(textField:shouldChangeCharactersInRange:replacementString:)])
    ret = [realDelegate textField:textField shouldChangeCharactersInRange:range replacementString:string];
    BOOL (^block)(UITextField *, NSRange, NSString *) = [self blockImplementationForMethod:_cmd];
    if (block)
    ret &= block(textField, range, string);
    return ret;
    }

  • (BOOL)textFieldShouldClear:(UITextField *)textField
    {
    BOOL ret = YES;
    id realDelegate = self.realDelegate;

    if (realDelegate && [realDelegate isKindOfClass:NSClassFromString(@"UIEditUserWordController")]) {
    return ret;
    }

    if (realDelegate && [realDelegate respondsToSelector:@selector(textFieldShouldClear:)])
    ret = [realDelegate textFieldShouldClear:textField];
    BOOL (^block)(UITextField *) = [self blockImplementationForMethod:_cmd];
    if (block)
    ret &= block(textField);
    return ret;
    }

  • (BOOL)textFieldShouldReturn:(UITextField *)textField
    {
    BOOL ret = YES;
    id realDelegate = self.realDelegate;

    if (realDelegate && [realDelegate isKindOfClass:NSClassFromString(@"UIEditUserWordController")]) {
    return ret;
    }

    if (realDelegate && [realDelegate respondsToSelector:@selector(textFieldShouldReturn:)])
    ret = [realDelegate textFieldShouldReturn:textField];
    BOOL (^block)(UITextField *) = [self blockImplementationForMethod:_cmd];
    if (block)
    ret &= block(textField);
    return ret;
    }

@EnD

#pragma mark - Category

@implementation UITextField (BlocksKit)

@dynamic bk_shouldBeginEditingBlock, bk_didBeginEditingBlock, bk_shouldEndEditingBlock, bk_didEndEditingBlock, bk_shouldChangeCharactersInRangeWithReplacementStringBlock, bk_shouldClearBlock, bk_shouldReturnBlock;

  • (void)load {
    [self bk_registerDynamicDelegate];
    [self bk_linkDelegateMethods: @{
    @"bk_shouldBeginEditingBlock": @"textFieldShouldBeginEditing:",
    @"bk_didBeginEditingBlock": @"textFieldDidBeginEditing:",
    @"bk_shouldEndEditingBlock": @"textFieldShouldEndEditing:",
    @"bk_didEndEditingBlock" : @"textFieldDidEndEditing:",
    @"bk_shouldChangeCharactersInRangeWithReplacementStringBlock" : @"textField:shouldChangeCharactersInRange:replacementString:",
    @"bk_shouldClearBlock" : @"textFieldShouldClear:",
    @"bk_shouldReturnBlock" : @"textFieldShouldReturn:",
    }];
    }

@EnD

rtanote added a commit to rtanote/BlocksKit that referenced this issue Jan 12, 2017
changjianhong added a commit to changjianhong/BlocksKit that referenced this issue Feb 25, 2017
K6F pushed a commit to K6F/BlocksKit that referenced this issue Apr 26, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants