Last active
March 18, 2021 17:48
-
-
Save zats/c075815e1fa24b001fb2 to your computer and use it in GitHub Desktop.
Implementing NSCopying, NSMutableCopying for immutable class with mutable counterpart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
@interface Node : NSObject <NSCopying, NSMutableCopying> | |
@property (nonatomic, weak, readonly) Node *parent; | |
@property (nonatomic, strong, readonly) Node *left; | |
@property (nonatomic, strong, readonly) Node *right; | |
- (instancetype)initWithParent:(Node *)parent left:(Node *)left right:(Node *)right; | |
@end | |
@interface MutableNode : Node | |
@property (nonatomic, weak) Node *parent; | |
@property (nonatomic, strong) Node *left; | |
@property (nonatomic, strong) Node *right; | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "Node.h" | |
@interface Node () | |
@property (nonatomic, weak) Node *parent; | |
@property (nonatomic, strong) Node *left; | |
@property (nonatomic, strong) Node *right; | |
@end | |
@implementation Node | |
- (instancetype)initWithParent:(Node *)parent left:(Node *)left right:(Node *)right { | |
self = [super init]; | |
if (!self) { | |
return nil; | |
} | |
self.parent = parent; | |
self.left = left; | |
self.right = right; | |
return self; | |
} | |
- (id)copyWithZone:(NSZone *)zone { | |
return self; | |
} | |
- (id)mutableCopyWithZone:(NSZone *)zone { | |
MutableNode *node = [[MutableNode allocWithZone:zone] init]; | |
node.parent = self.parent; | |
node.left = self.left; | |
node.right = self.right; | |
return node; | |
} | |
- (void)setLeft:(Node *)left { | |
_left = left; | |
if (left.parent != self) { | |
left.parent = self; | |
} | |
} | |
- (void)setRight:(Node *)right { | |
_right = right; | |
if (right.parent != self) { | |
right.parent = self; | |
} | |
} | |
- (NSString *)description { | |
NSMutableString *string = [NSMutableString stringWithFormat:@"<%@:%p>", [self class], self]; | |
if (!self.parent && !self.left && !self.right) { | |
return [string copy]; | |
} | |
[string appendString:@" {"]; | |
if (self.parent) { | |
[string appendFormat:@" parent = <%@:%p>", [self.parent class], self.parent]; | |
} | |
if (self.left) { | |
[string appendFormat:@" left = <%@:%p>", [self.left class], self.left]; | |
} | |
if (self.right) { | |
[string appendFormat:@" right = <%@:%p>", [self.right class], self.right]; | |
} | |
[string appendString:@" }"]; | |
return [string copy]; | |
} | |
@end | |
@implementation MutableNode | |
- (id)copyWithZone:(NSZone *)zone { | |
Node *node = [[Node allocWithZone:zone] init]; | |
[node setValue:self.parent forKey:@"parent"]; | |
[node setValue:self.left forKey:@"left"]; | |
[node setValue:self.right forKey:@"right"]; | |
return node; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment