iOS는 어떻게 사용자 정의 클래스의 심층 복사를 실현합니까?

2575 단어
NSCopying 프로토콜을 준수하여copyWithZone 방법을 실현하고 방법에서 대상을 새로 만든 다음에 OC와 Swift에 있어 차이가 있다. OC는runtime를 이용하여 원 대상의 속성 목록을 얻은 다음에 KVC를 통해 새로운 대상에게 값을 부여한다. setValueForUndefinedKey 함수를 실현해야 한다는 것을 주의한다.Swift는 Mirror 반사를 통해 원래 객체의 속성을 동적으로 가져온 다음 값을 지정합니다.

OC 방법:

CustomModel *m1 = [CustomModel new];
m1.name = @"Shaw";
m1.age = 27;
CustomModel *m2 = [m1 copy];
m2.name = @"CTT";
m2.age = 28;
    
NSLog(@"%@&%@", m1.name, m2.name);
//  :Shaw&CTT

@interface CustomModel : NSObject 
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) int age;
@end

@implementation CustomModel

- (id)copyWithZone:(NSZone *)zone {
    CustomModel *copy = [[[self class] alloc] init];
    unsigned int propertyCount = 0;
    objc_property_t *propertyList = class_copyPropertyList([self class], &propertyCount);
    for (int i = 0; i < propertyCount; i++ ) {
        objc_property_t thisProperty = propertyList[i];
        const char* propertyCName = property_getName(thisProperty);
        NSString *propertyName = [NSString stringWithCString:propertyCName encoding:NSUTF8StringEncoding];
        id value = [self valueForKey:propertyName];
        [copy setValue:value forKey:propertyName];
    }
    return copy;
}
//  , Runtime , hash , 
- (void)setValue:(id)value forUndefinedKey:(NSString *)key {}

Swift 방식:


NSObject에 확장자를 써서 NSCopying 프로토콜을 준수하도록 합니다. 또한 사용자 정의 클래스도 setValueForUndefinedKey 함수를 실현해야 합니다.
let m1 = CustomModel()
m1.name = "Shaw"
m1.age = 27
        
let m2 = m1.copy() as! CustomModel
m2.name = "CTT"
m2.age = 28
        
print("\(m1.age!)&\(m2.age!)")
//  :27&28

class CustomModel: NSObject {
    public var name: String?
    public var age: Int?
    override func setValue(_ value: Any?, forUndefinedKey key: String) {}
}

extension NSObject: NSCopying {
    public func copy(with zone: NSZone? = nil) -> Any {
        let copy = self.classForCoder.alloc()
        let mirror = Mirror(reflecting: self)
        for (label, value) in mirror.children {
            guard let label = label else { continue }
            copy.setValue(value, forKey: label)
        }
        return copy
    }
}

만약 부류가 깊은 복사를 실현했다면, 하류는 어떻게 깊은 복사를 실현합니까?만약 부모 클래스가 깊은 복사를 실현하지 못한다면, 하위 클래스는 어떻게 실현합니까?


부모 클래스가 깊은 복사를 실현한 후 하위 클래스는copyWithZone 방법을 다시 쓰고 방법 내부에서 부모 클래스의copyWithZone 방법을 호출한 후에 자신의 속성 처리를 실현한다.부류가 깊은 복사를 실현하지 못했기 때문에 부류는 자신의 속성을 처리해야 할 뿐만 아니라 부류의 속성도 처리해야 한다.

좋은 웹페이지 즐겨찾기