mirror of
https://github.com/gnustep/libs-performance.git
synced 2025-02-14 23:51:19 +00:00
Cope with objects which can't be copied (ie -copy returns the receiver).
This commit is contained in:
parent
94eb232b96
commit
99e01fe21e
2 changed files with 46 additions and 4 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2019-08-08 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
* GSUniqued.m:
|
||||||
|
Add special case code for handling objcts which can't be copied.
|
||||||
|
|
||||||
2019-04-16 Richard Frith-Macdonald <rfm@gnu.org>
|
2019-04-16 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
* GSCache.h:
|
* GSCache.h:
|
||||||
|
|
45
GSUniqued.m
45
GSUniqued.m
|
@ -75,6 +75,8 @@ uRelease(id self, SEL _cmd)
|
||||||
|
|
||||||
@implementation GSUniqued
|
@implementation GSUniqued
|
||||||
|
|
||||||
|
static Class NSObjectClass;
|
||||||
|
|
||||||
+ (void) initialize
|
+ (void) initialize
|
||||||
{
|
{
|
||||||
if (Nil == GSUniquedClass)
|
if (Nil == GSUniquedClass)
|
||||||
|
@ -86,6 +88,7 @@ uRelease(id self, SEL _cmd)
|
||||||
iUnlock = [uniquedObjectsLock methodForSelector: @selector(unlock)];
|
iUnlock = [uniquedObjectsLock methodForSelector: @selector(unlock)];
|
||||||
uniquedObjects = NSCreateHashTable(
|
uniquedObjects = NSCreateHashTable(
|
||||||
NSNonRetainedObjectHashCallBacks, 10000);
|
NSNonRetainedObjectHashCallBacks, 10000);
|
||||||
|
NSObjectClass = [NSObject class];
|
||||||
GSUniquedClass = [GSUniqued class];
|
GSUniquedClass = [GSUniqued class];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,10 +116,33 @@ uRelease(id self, SEL _cmd)
|
||||||
Class u;
|
Class u;
|
||||||
|
|
||||||
aCopy = [anObject copyWithZone: NSDefaultMallocZone()];
|
aCopy = [anObject copyWithZone: NSDefaultMallocZone()];
|
||||||
|
if (aCopy == anObject)
|
||||||
|
{
|
||||||
|
/* Unable to make a copy ... that probably means the object
|
||||||
|
* is already unique and we can just return it.
|
||||||
|
*/
|
||||||
|
if (NO == [aCopy isKindOfClass: [NSString class]])
|
||||||
|
{
|
||||||
|
return aCopy;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NSMutableString *m;
|
||||||
|
|
||||||
|
/* We have different subclasses of NSString and we can't swizzle
|
||||||
|
* a constant string, so in that case we need to work with another
|
||||||
|
* type of string.
|
||||||
|
*/
|
||||||
|
m = [aCopy mutableCopy];
|
||||||
|
[aCopy release];
|
||||||
|
aCopy = [m copy];
|
||||||
|
[m release];
|
||||||
|
}
|
||||||
|
}
|
||||||
c = object_getClass(aCopy);
|
c = object_getClass(aCopy);
|
||||||
|
|
||||||
[classLock lock];
|
[classLock lock];
|
||||||
u = [classMap objectForKey: c];
|
u = [classMap objectForKey: (id<NSCopying>)c];
|
||||||
if (Nil == u)
|
if (Nil == u)
|
||||||
{
|
{
|
||||||
const char *cn = class_getName(c);
|
const char *cn = class_getName(c);
|
||||||
|
@ -126,18 +152,25 @@ uRelease(id self, SEL _cmd)
|
||||||
sprintf(name, "GSUniqued%s", cn);
|
sprintf(name, "GSUniqued%s", cn);
|
||||||
u = objc_allocateClassPair(c, name, 0);
|
u = objc_allocateClassPair(c, name, 0);
|
||||||
|
|
||||||
method = class_getInstanceMethod([NSObject class],
|
method = class_getInstanceMethod(NSObjectClass,
|
||||||
@selector(dealloc));
|
@selector(dealloc));
|
||||||
class_addMethod(u, @selector(dealloc),
|
class_addMethod(u, @selector(dealloc),
|
||||||
(IMP)uDealloc, method_getTypeEncoding(method));
|
(IMP)uDealloc, method_getTypeEncoding(method));
|
||||||
|
|
||||||
method = class_getInstanceMethod([NSObject class],
|
method = class_getInstanceMethod(NSObjectClass,
|
||||||
@selector(release));
|
@selector(release));
|
||||||
class_addMethod(u, @selector(release),
|
class_addMethod(u, @selector(release),
|
||||||
(IMP)uRelease, method_getTypeEncoding(method));
|
(IMP)uRelease, method_getTypeEncoding(method));
|
||||||
|
|
||||||
|
method = class_getInstanceMethod(GSUniquedClass,
|
||||||
|
@selector(copyUniqued));
|
||||||
|
class_addMethod(u, @selector(copyUniqued),
|
||||||
|
class_getMethodImplementation(GSUniquedClass,
|
||||||
|
@selector(copyUniqued)),
|
||||||
|
method_getTypeEncoding(method));
|
||||||
|
|
||||||
objc_registerClassPair(u);
|
objc_registerClassPair(u);
|
||||||
[classMap setObject: u forKey: c];
|
[classMap setObject: u forKey: (id<NSCopying>)c];
|
||||||
}
|
}
|
||||||
[classLock unlock];
|
[classLock unlock];
|
||||||
|
|
||||||
|
@ -162,6 +195,10 @@ uRelease(id self, SEL _cmd)
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (id) copyUniqued
|
||||||
|
{
|
||||||
|
return [self retain];
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation NSObject (GSUniqued)
|
@implementation NSObject (GSUniqued)
|
||||||
|
|
Loading…
Reference in a new issue