iOS_EXC_BAD_ACCESS 异常修复体验

一丶原因

  if ([cls respondsToSelector:item.itemSizeSel]) {
            CGSize size = ((CGSize(*)(id, SEL, id)) objc_msgSend)(cls, item.itemSizeSel, model);
            layoutItem.size = size;
        }
        SEL sel = NSSelectorFromString(@"itemMargin:");
        if ([cls respondsToSelector:sel]) {
            UIEdgeInsets insets = ((UIEdgeInsets(*)(id, SEL, id)) objc_msgSend)(cls, sel, model);
            layoutItem.margin = insets;
        }

运行:


图片.png

bt:


图片.png

二丶解决:

使用方法签名:

       id model = item.rawModel;
        if ([cls respondsToSelector:item.itemSizeSel]) {
            CGSize size;
            NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:"{CGSize=dd}#:@"];
            NSInvocation *inv = [NSInvocation invocationWithMethodSignature:signature];
            inv.target = cls;
            inv.selector = item.itemSizeSel;
            [inv setArgument:&model atIndex:2];
            [inv invoke];
            [inv getReturnValue:&size];
            layoutItem.size = size;
        }
        SEL sel = NSSelectorFromString(@"itemMargin:");
        if ([cls respondsToSelector:sel]) {
            UIEdgeInsets insets;
            NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:"{UIEdgeInsets=dddd}#:@"];
            NSInvocation *inv = [NSInvocation invocationWithMethodSignature:signature];
            inv.target = cls;
            inv.selector = sel;
            [inv setArgument:&model atIndex:2];
            [inv invoke];
            [inv getReturnValue:&insets];
            layoutItem.margin = insets;
        }

附带ocrtTypeEncodings

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html

三丶原因:

OBJC_EXPORT void
objc_msgSend(void /* id self, SEL op, ... */ )
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

系统performSelector

+ (id)performSelector:(SEL)sel {
    if (!sel) [self doesNotRecognizeSelector:sel];
    return ((id(*)(id, SEL))objc_msgSend)((id)self, sel);
}

查一下文档:


iOS_EXC_BAD_ACCESS 异常修复体验_第1张图片
图片.png

错误是报在objc_msgSend附近
继续看:


图片.png

第一次返回是id类型的强转成CGSize;
第二次返回是id类型的强转成UIEdgeInsets;
This occurs when a new object is allocated in the memory previously occupied by the deallocated object
当一个新对象被分配到之前被释放对象占用的内存中时,就会发生这种情况

参考:
https://developer.apple.com/library/archive/technotes/tn2151/_index.html

你可能感兴趣的:(iOS_EXC_BAD_ACCESS 异常修复体验)