一丶原因
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;
}
运行:
bt:
二丶解决:
使用方法签名:
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
三丶原因:
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);
}
查一下文档:
错误是报在objc_msgSend附近
继续看:
第一次返回是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