Skip to content

Instantly share code, notes, and snippets.

@zats
Last active March 18, 2021 17:48
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zats/c075815e1fa24b001fb2 to your computer and use it in GitHub Desktop.
Save zats/c075815e1fa24b001fb2 to your computer and use it in GitHub Desktop.
Implementing NSCopying, NSMutableCopying for immutable class with mutable counterpart
#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
#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