YYModel icon indicating copy to clipboard operation
YYModel copied to clipboard

CGRect, CGSize 等 Struct 无法双向转换,`- [ yy_modelToJSONObject]` 方法会丢失这些数据

Open heistings opened this issue 6 years ago • 2 comments

尽管 +[ yy_modelWithDictionary] 方法支持 NSValue 作为 value type,并能够成功 setup model;但是 - [ yy_modelToJSONObject] 正确的生成 NSValue;下面例子中的 dict 对象打印出来是一个空的字典。

YYModel 无法通过以下测试:

#import <UIKit/UIKit.h>

@interface YYCGStructTestObject : NSObject

@property (nonatomic) CGPoint point;
@property (nonatomic) CGVector vector;
@property (nonatomic) CGSize size;
@property (nonatomic) CGRect rect;
@property (nonatomic) CGAffineTransform affine_transform;
@property (nonatomic) UIEdgeInsets edge_insets;
@property (nonatomic) NSDirectionalEdgeInsets directional_edge_insets;
@property (nonatomic) UIOffset offset;
@property (nonatomic) NSRange range;

@end
- (void)testYYModelWithCGStruct
{
    YYCGStructTestObject *object = [YYCGStructTestObject new];
    object.point = CGPointMake(10, 10);
    object.vector = CGVectorMake(5, 5);
    object.size = CGSizeMake(100, 100);
    object.rect = CGRectMake(100, 100, 100, 100);
    object.affine_transform = CGAffineTransformMake(5, 5, 5, 5, 5, 5);
    object.edge_insets = UIEdgeInsetsMake(5, 5, 5, 5);
    object.directional_edge_insets = NSDirectionalEdgeInsetsMake(5, 5, 5, 5);
    object.offset = UIOffsetMake(5, 5);
    object.range = NSMakeRange(1, 1);
    
    NSDictionary *dict = [object yy_modelToJSONObject];
    
    YYCGStructTestObject *targetObject = [YYCGStructTestObject yy_modelWithDictionary:dict];
    XCTAssert(CGPointEqualToPoint(object.point, targetObject.point));
    XCTAssert(CGSizeEqualToSize(object.size, targetObject.size));
//    XCTAssert([object.vector isEqualToValue:targetObject.vector]);
//    XCTAssert([object.size isEqualToValue:targetObject.size]);
//    XCTAssert([object.rect isEqualToValue:targetObject.rect]);
//    XCTAssert([object.affine_transform isEqualToValue:targetObject.affine_transform]);
//    XCTAssert([object.edge_insets isEqualToValue:targetObject.edge_insets]);
//    XCTAssert([object.directional_edge_insets isEqualToValue:targetObject.directional_edge_insets]);
//    XCTAssert([object.offset isEqualToValue:targetObject.offset]);
//    XCTAssert([object.range isEqualToValue:targetObject.range]);
}

heistings avatar Jan 26 '18 07:01 heistings

我觉得我可能知道原因了:

else {
            YYEncodingType type = propertyMeta->_type & YYEncodingTypeMask;
            switch (type) {
                case YYEncodingTypeObject: {
                    id v = ((id (*)(id, SEL))(void *) objc_msgSend)((id)model, propertyMeta->_getter);
                    value = ModelToJSONObjectRecursive(v);
                    if (value == (id)kCFNull) value = nil;
                } break;
                case YYEncodingTypeClass: {
                    Class v = ((Class (*)(id, SEL))(void *) objc_msgSend)((id)model, propertyMeta->_getter);
                    value = v ? NSStringFromClass(v) : nil;
                } break;
                case YYEncodingTypeSEL: {
                    SEL v = ((SEL (*)(id, SEL))(void *) objc_msgSend)((id)model, propertyMeta->_getter);
                    value = v ? NSStringFromSelector(v) : nil;
                } break;
                case YYEncodingTypeStruct: {
                    // TODO: 无论是自定义的 struct,还是 CGRect, CGPoint,都会进入这个分支
                    // 如果不能确定具体的类型,则无法处理
                } break;
                default: break;
            }
        }

heistings avatar Jan 26 '18 08:01 heistings

@heistings 我也出现了这个问题,所以你最后是怎么解决这问题的....我在 YYModel 中,你贴代码的位置并没有看到 YYEncodingTypeStruct 分支,该分支是你自己添加的吗?最后你是如何解决这个问题的?

rakuyoMo avatar Aug 24 '18 06:08 rakuyoMo