-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDSABaseObject.m
More file actions
149 lines (123 loc) · 5.65 KB
/
DSABaseObject.m
File metadata and controls
149 lines (123 loc) · 5.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*
Project: DSA-SpielHelfer
Copyright (C) 2025 Free Software Foundation
Author: Sebastian Reitenbach
Created: 2025-09-07 20:55:11 +0200 by sebastia
This application is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This application is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#import "DSABaseObject.h"
@implementation DSABaseObject
- (NSString *)description
{
NSMutableString *descriptionString = [NSMutableString stringWithFormat:@"%@:\n", [self class]];
// Start from the current class
Class currentClass = [self class];
// Loop through the class hierarchy
while (currentClass && currentClass != [NSObject class])
{
// Get the list of properties for the current class
unsigned int propertyCount;
objc_property_t *properties = class_copyPropertyList(currentClass, &propertyCount);
// Iterate through all properties of the current class
for (unsigned int i = 0; i < propertyCount; i++)
{
objc_property_t property = properties[i];
const char *propertyName = property_getName(property);
NSString *key = [NSString stringWithUTF8String:propertyName];
// Get the value of the property using KVC (Key-Value Coding)
id value = [self valueForKey:key];
// Append the property and its value to the description string
[descriptionString appendFormat:@"%@ = %@\n", key, value];
}
// Free the property list since it's a C array
free(properties);
// Move to the superclass
currentClass = [currentClass superclass];
}
return descriptionString;
}
// Ignores readonly variables with the assumption
// they are all calculated
- (id)copyWithZone:(NSZone *)zone
{
//NSLog(@"DSABaseObject copyWithZone called!");
// Neues Objekt vom selben Typ erzeugen
DSABaseObject *copy = [[[self class] allocWithZone:zone] init];
Class currentClass = [self class];
while (currentClass != [NSObject class]) {
unsigned int propertyCount;
objc_property_t *properties = class_copyPropertyList(currentClass, &propertyCount);
for (unsigned int i = 0; i < propertyCount; i++) {
objc_property_t property = properties[i];
const char *propertyName = property_getName(property);
NSString *key = [NSString stringWithUTF8String:propertyName];
const char *attributes = property_getAttributes(property);
NSString *attributesString = [NSString stringWithUTF8String:attributes];
if ([attributesString containsString:@",R"]) {
// readonly -> wird übersprungen
continue;
}
id value = [self valueForKey:key];
if (!value) continue;
// --- NSArray ---
if ([value isKindOfClass:[NSArray class]]) {
NSMutableArray *copiedArray = [[NSMutableArray alloc] initWithCapacity:[(NSArray *)value count]];
for (id item in (NSArray *)value) {
if ([item conformsToProtocol:@protocol(NSCopying)]) {
[copiedArray addObject:[item copyWithZone:zone]];
} else {
[copiedArray addObject:item];
}
}
[copy setValue:[NSArray arrayWithArray:copiedArray] forKey:key];
}
// --- NSDictionary ---
else if ([value isKindOfClass:[NSDictionary class]]) {
NSMutableDictionary *copiedDict = [[NSMutableDictionary alloc] initWithCapacity:[(NSDictionary *)value count]];
for (id dictKey in (NSDictionary *)value) {
id item = value[dictKey];
if ([item conformsToProtocol:@protocol(NSCopying)]) {
copiedDict[dictKey] = [item copyWithZone:zone];
} else {
copiedDict[dictKey] = item;
}
}
[copy setValue:[NSDictionary dictionaryWithDictionary:copiedDict] forKey:key];
}
// --- NSSet ---
else if ([value isKindOfClass:[NSSet class]]) {
NSMutableSet *copiedSet = [[NSMutableSet alloc] initWithCapacity:[(NSSet *)value count]];
for (id item in (NSSet *)value) {
if ([item conformsToProtocol:@protocol(NSCopying)]) {
[copiedSet addObject:[item copyWithZone:zone]];
} else {
[copiedSet addObject:item];
}
}
[copy setValue:[NSSet setWithSet:copiedSet] forKey:key];
}
// --- alle anderen Objekte, die NSCopying unterstützen ---
else if ([value conformsToProtocol:@protocol(NSCopying)]) {
[copy setValue:[value copyWithZone:zone] forKey:key];
}
// --- Fallback: shallow copy ---
else {
[copy setValue:value forKey:key];
}
}
free(properties);
currentClass = [currentClass superclass];
}
return copy;
}
@end