mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 08:26:27 +00:00
memory usage interrogation
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@38799 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
8af37de38b
commit
3efbfa42e2
17 changed files with 428 additions and 16 deletions
21
ChangeLog
21
ChangeLog
|
@ -1,3 +1,24 @@
|
|||
2015-07-15 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Headers/GNUstepBase/GSIMap.h:
|
||||
* Headers/GNUstepBase/NSObject+GNUstepBase.h:
|
||||
* Source/Additions/GSMime.m:
|
||||
* Source/Additions/NSObject+GNUstepBase.m:
|
||||
* Source/GSArray.m:
|
||||
* Source/GSCountedSet.m:
|
||||
* Source/GSDictionary.m:
|
||||
* Source/GSPrivate.h:
|
||||
* Source/GSSet.m:
|
||||
* Source/GSString.m:
|
||||
* Source/NSArray.m:
|
||||
* Source/NSData.m:
|
||||
* Source/NSDictionary.m:
|
||||
* Source/NSObject.m:
|
||||
* Source/NSSet.m:
|
||||
* Source/NSString.m:
|
||||
Extension API to interrogate object memory usage (stolen from
|
||||
GSCache and modified a bit).
|
||||
|
||||
2015-07-14 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/NSPropertyList.m: Write xml document headers referring to
|
||||
|
|
|
@ -1259,6 +1259,37 @@ GSIMapInitWithZoneAndCapacity(GSIMapTable map, NSZone *zone, uintptr_t capacity)
|
|||
GSIMapMoreNodes(map, capacity);
|
||||
}
|
||||
|
||||
GS_STATIC_INLINE NSUInteger
|
||||
GSIMapSize(GSIMapTable map)
|
||||
{
|
||||
NSUInteger index;
|
||||
NSUInteger size;
|
||||
GSIMapNode node;
|
||||
|
||||
/* Map table plus arrays of pointers to chunks
|
||||
*/
|
||||
size = sizeof(*map) + map->chunkCount * sizeof(void*);
|
||||
|
||||
/* Add the array of buckets.
|
||||
*/
|
||||
size += map->bucketCount * sizeof(GSIMapBucket_t);
|
||||
|
||||
/* Add the free nodes.
|
||||
*/
|
||||
for (node = map->freeNodes; 0 != node; node = node->nextInBucket)
|
||||
{
|
||||
size += sizeof(GSIMapNode_t);
|
||||
}
|
||||
|
||||
/* Add the used nodes (in the buckets).
|
||||
*/
|
||||
for (index = 0; index < map->bucketCount; index++)
|
||||
{
|
||||
size += sizeof(GSIMapNode_t) * map->buckets[index].nodeCount;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -36,6 +36,8 @@ extern "C" {
|
|||
|
||||
#if OS_API_VERSION(GS_API_NONE,GS_API_LATEST)
|
||||
|
||||
@class NSHashTable;
|
||||
|
||||
@interface NSObject (GNUstepBase)
|
||||
|
||||
/**
|
||||
|
@ -96,6 +98,15 @@ extern "C" {
|
|||
|
||||
@end
|
||||
|
||||
/** This is an informal protocol ... classes may implement the method to
|
||||
* report how much memory is used by the instance and any objects it acts
|
||||
* as a container for. The method should return zero if calling the
|
||||
* superclass version returns zero (ie the object is in the exclude table).
|
||||
*/
|
||||
@interface NSObject(MemorySize)
|
||||
- (NSUInteger) sizeInBytes: (NSHashTable*)exclude;
|
||||
@end
|
||||
|
||||
/** This is an informal protocol ... classes may implement the method and
|
||||
* register themselves to have it called on process exit.
|
||||
*/
|
||||
|
|
|
@ -4085,6 +4085,21 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
|
|||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
- (NSUInteger) sizeInBytes: (NSHashTable*)exclude
|
||||
{
|
||||
NSUInteger size = [super sizeInBytes: exclude];
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
size += [name sizeInBytes: exclude];
|
||||
size += [value sizeInBytes: exclude];
|
||||
size += [objects sizeInBytes: exclude];
|
||||
size += [params sizeInBytes: exclude];
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
@ -6488,6 +6503,18 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
|
|||
return hdr;
|
||||
}
|
||||
|
||||
- (NSUInteger) sizeInBytes: (NSHashTable*)exclude
|
||||
{
|
||||
NSUInteger size = [super sizeInBytes: exclude];
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
size += [headers sizeInBytes: exclude];
|
||||
size += [content sizeInBytes: exclude];
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation GSMimeDocument (Private)
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#import "common.h"
|
||||
#import "Foundation/NSArray.h"
|
||||
#import "Foundation/NSException.h"
|
||||
#import "Foundation/NSHashTable.h"
|
||||
#import "Foundation/NSLock.h"
|
||||
#import "GNUstepBase/NSObject+GNUstepBase.h"
|
||||
#import "GNUstepBase/NSDebug+GNUstepBase.h"
|
||||
|
@ -293,6 +294,33 @@ handleExit()
|
|||
|
||||
#else
|
||||
|
||||
NSUInteger
|
||||
GSPrivateMemorySize(NSObject *self, NSHashTable *exclude)
|
||||
{
|
||||
if (0 == NSHashGet(exclude, self))
|
||||
{
|
||||
NSHashInsert(exclude, self);
|
||||
return class_getInstanceSize(object_getClass(self));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@interface NSObject (MemorySize)
|
||||
+ (NSUInteger) sizeInBytes: (NSHashTable*)exclude
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
- (NSUInteger) sizeInBytes: (NSHashTable*)exclude
|
||||
{
|
||||
if (0 == NSHashGet(exclude, self))
|
||||
{
|
||||
NSHashInsert(exclude, self);
|
||||
return class_getInstanceSize(object_getClass(self));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@end
|
||||
|
||||
/* Dummy implementation
|
||||
*/
|
||||
@implementation NSObject(GSCleanup)
|
||||
|
|
|
@ -387,6 +387,7 @@ static Class GSInlineArrayClass;
|
|||
state->state += count;
|
||||
return count;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#if !GS_WITH_GC
|
||||
|
@ -970,6 +971,23 @@ static Class GSInlineArrayClass;
|
|||
state->itemsPtr = stackbuf;
|
||||
return count;
|
||||
}
|
||||
|
||||
- (NSUInteger) sizeInBytes: (NSHashTable*)exclude
|
||||
{
|
||||
NSUInteger size = GSPrivateMemorySize(self, exclude);
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
NSUInteger count = _count;
|
||||
|
||||
size += _capacity*sizeof(void*);
|
||||
while (count-- > 0)
|
||||
{
|
||||
size += [[self objectAtIndex: count] sizeInBytes: exclude];
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
|
|
|
@ -393,4 +393,30 @@ static GC_descr nodeDesc; // Type descriptor for map node.
|
|||
return GSIMapCountByEnumeratingWithStateObjectsCount
|
||||
(&map, state, stackbuf, len);
|
||||
}
|
||||
|
||||
- (NSUInteger) sizeInBytes: (NSHashTable*)exclude
|
||||
{
|
||||
NSUInteger size = GSPrivateMemorySize(self, exclude);
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
NSUInteger count = [self count];
|
||||
|
||||
size += GSIMapSize(&map) - sizeof(map);
|
||||
if (count > 0)
|
||||
{
|
||||
NSAutoreleasePool *pool = [NSAutoreleasePool new];
|
||||
NSEnumerator *enumerator = [self keyEnumerator];
|
||||
NSObject *k;
|
||||
|
||||
while ((k = [enumerator nextObject]) != nil)
|
||||
{
|
||||
size += [k sizeInBytes: exclude];
|
||||
}
|
||||
[pool release];
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -364,6 +364,34 @@ static SEL objSel;
|
|||
return GSIMapCountByEnumeratingWithStateObjectsCount
|
||||
(&map, state, stackbuf, len);
|
||||
}
|
||||
|
||||
- (NSUInteger) sizeInBytes: (NSHashTable*)exclude
|
||||
{
|
||||
NSUInteger size = GSPrivateMemorySize(self, exclude);
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
NSUInteger count = [self count];
|
||||
|
||||
size += GSIMapSize(&map) - sizeof(map);
|
||||
if (count > 0)
|
||||
{
|
||||
NSAutoreleasePool *pool = [NSAutoreleasePool new];
|
||||
NSEnumerator *enumerator = [self keyEnumerator];
|
||||
NSObject *k;
|
||||
|
||||
while ((k = [enumerator nextObject]) != nil)
|
||||
{
|
||||
NSObject *o = [self objectForKey: k];
|
||||
|
||||
size += [k sizeInBytes: exclude] + [o sizeInBytes: exclude];
|
||||
}
|
||||
[pool release];
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation GSMutableDictionary
|
||||
|
|
|
@ -571,6 +571,16 @@ uint32_t
|
|||
GSPrivateFinishHash(uint32_t s0, uint32_t s1, uint32_t totalLength)
|
||||
GS_ATTRIB_PRIVATE;
|
||||
|
||||
@class NSHashTable;
|
||||
/* If 'self' is not a member of 'exclude', adds to the hash
|
||||
* table and returns the memory footprint of 'self' assuming
|
||||
* it contains no pointers and has no extra memory allocated.
|
||||
* Otherwise returns 0.
|
||||
*/
|
||||
NSUInteger
|
||||
GSPrivateMemorySize(NSObject *self, NSHashTable *exclude)
|
||||
GS_ATTRIB_PRIVATE;
|
||||
|
||||
/* Return the current thread ID as an NSUInteger.
|
||||
* Ideally, we use the operating-system's notion of a thread ID so
|
||||
* that external process monitoring software will be using the same
|
||||
|
|
|
@ -537,6 +537,32 @@ static Class mutableSetClass;
|
|||
return GSIMapCountByEnumeratingWithStateObjectsCount
|
||||
(&map, state, stackbuf, len);
|
||||
}
|
||||
|
||||
- (NSUInteger) sizeInBytes: (NSHashTable*)exclude
|
||||
{
|
||||
NSUInteger size = GSPrivateMemorySize(self, exclude);
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
NSUInteger count = [self count];
|
||||
|
||||
size += GSIMapSize(&map) - sizeof(map);
|
||||
if (count > 0)
|
||||
{
|
||||
NSAutoreleasePool *pool = [NSAutoreleasePool new];
|
||||
NSEnumerator *enumerator = [self keyEnumerator];
|
||||
NSObject *k;
|
||||
|
||||
while ((k = [enumerator nextObject]) != nil)
|
||||
{
|
||||
size += [k sizeInBytes: exclude];
|
||||
}
|
||||
[pool release];
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation GSMutableSet
|
||||
|
|
|
@ -1087,6 +1087,16 @@ tsbytes(uintptr_t s, char *buf)
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
- (NSUInteger) sizeInBytes: (NSHashTable*)exclude
|
||||
{
|
||||
if (0 == NSMapGet(exclude, self))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 8;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
|
@ -3834,6 +3844,21 @@ transmute(GSStr self, NSString *aString)
|
|||
freeWhenDone: flag];
|
||||
}
|
||||
|
||||
- (NSUInteger) sizeInBytes: (NSHashTable*)exclude
|
||||
{
|
||||
NSUInteger size = GSPrivateMemorySize(self, exclude);
|
||||
|
||||
if (size > 0 && _flags.owned)
|
||||
{
|
||||
size += _count;
|
||||
if (_flags.wide)
|
||||
{
|
||||
size += _count;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
@ -5640,6 +5665,21 @@ NSAssert(_flags.owned == 1 && _zone != 0, NSInternalInconsistencyException);
|
|||
return _count;
|
||||
}
|
||||
|
||||
- (NSUInteger) sizeInBytes: (NSHashTable*)exclude
|
||||
{
|
||||
NSUInteger size = GSPrivateMemorySize(self, exclude);
|
||||
|
||||
if (size > 0 && _flags.owned)
|
||||
{
|
||||
size += _capacity;
|
||||
if (_flags.wide)
|
||||
{
|
||||
size += _capacity;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
|
|
@ -1771,6 +1771,7 @@ compare(id elem1, id elem2, void* context)
|
|||
{
|
||||
[self enumerateObjectsWithOptions: 0 usingBlock: aBlock];
|
||||
}
|
||||
|
||||
- (void) enumerateObjectsWithOptions: (NSEnumerationOptions)opts
|
||||
usingBlock: (GSEnumeratorBlock)aBlock
|
||||
{
|
||||
|
@ -1792,18 +1793,18 @@ compare(id elem1, id elem2, void* context)
|
|||
FOR_IN (id, obj, enumerator)
|
||||
GS_DISPATCH_SUBMIT_BLOCK(enumQueueGroup, enumQueue, if (YES == shouldStop) {return;}, return, aBlock, obj, count, &shouldStop);
|
||||
if (isReverse)
|
||||
{
|
||||
count--;
|
||||
}
|
||||
{
|
||||
count--;
|
||||
}
|
||||
else
|
||||
{
|
||||
count++;
|
||||
}
|
||||
{
|
||||
count++;
|
||||
}
|
||||
|
||||
if (shouldStop)
|
||||
{
|
||||
break;
|
||||
}
|
||||
{
|
||||
break;
|
||||
}
|
||||
END_FOR_IN(enumerator)
|
||||
GS_DISPATCH_TEARDOWN_QUEUE_AND_GROUP_FOR_ENUMERATION(enumQueue, opts)
|
||||
}
|
||||
|
@ -1888,8 +1889,8 @@ compare(id elem1, id elem2, void* context)
|
|||
passingTest: predicate];
|
||||
}
|
||||
|
||||
- (NSUInteger)indexOfObjectWithOptions: (NSEnumerationOptions)opts
|
||||
passingTest: (GSPredicateBlock)predicate
|
||||
- (NSUInteger) indexOfObjectWithOptions: (NSEnumerationOptions)opts
|
||||
passingTest: (GSPredicateBlock)predicate
|
||||
{
|
||||
/* TODO: Concurrency. */
|
||||
id<NSFastEnumeration> enumerator = self;
|
||||
|
@ -1954,13 +1955,30 @@ compare(id elem1, id elem2, void* context)
|
|||
return [self indexOfObjectWithOptions: 0 passingTest: predicate];
|
||||
}
|
||||
|
||||
- (NSUInteger)indexOfObjectAtIndexes: (NSIndexSet*)indexSet
|
||||
options: (NSEnumerationOptions)opts
|
||||
passingTest: (GSPredicateBlock)predicate
|
||||
- (NSUInteger) indexOfObjectAtIndexes: (NSIndexSet*)indexSet
|
||||
options: (NSEnumerationOptions)opts
|
||||
passingTest: (GSPredicateBlock)predicate
|
||||
{
|
||||
return [[self objectsAtIndexes: indexSet]
|
||||
indexOfObjectWithOptions: 0
|
||||
passingTest: predicate];
|
||||
indexOfObjectWithOptions: 0
|
||||
passingTest: predicate];
|
||||
}
|
||||
|
||||
- (NSUInteger) sizeInBytes: (NSHashTable*)exclude
|
||||
{
|
||||
NSUInteger size = [super sizeInBytes: exclude];
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
NSUInteger count = [self count];
|
||||
|
||||
size += count*sizeof(void*);
|
||||
while (count-- > 0)
|
||||
{
|
||||
size += [[self objectAtIndex: count] sizeInBytes: exclude];
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
@end
|
||||
|
||||
|
|
|
@ -1980,6 +1980,18 @@ failure:
|
|||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSUInteger) sizeInBytes: (NSHashTable*)exclude
|
||||
{
|
||||
NSUInteger size = [super sizeInBytes: exclude];
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
size += [self length];
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
|
@ -3282,6 +3294,13 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
|
|||
}
|
||||
}
|
||||
|
||||
- (NSUInteger) sizeInBytes: (NSHashTable*)exclude
|
||||
{
|
||||
NSUInteger size = GSPrivateMemorySize(self, exclude);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
@ -3339,6 +3358,17 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
|
|||
return self;
|
||||
}
|
||||
|
||||
- (NSUInteger) sizeInBytes: (NSHashTable*)exclude
|
||||
{
|
||||
NSUInteger size = GSPrivateMemorySize(self, exclude);
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
size += length;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#if GS_WITH_GC
|
||||
|
@ -4162,6 +4192,17 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
|
|||
length = size;
|
||||
}
|
||||
|
||||
- (NSUInteger) sizeInBytes: (NSHashTable*)exclude
|
||||
{
|
||||
NSUInteger size = GSPrivateMemorySize(self, exclude);
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
size += capacity;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#if GS_WITH_GC
|
||||
|
|
|
@ -1229,6 +1229,33 @@ compareIt(id o1, id o2, void* context)
|
|||
[self subclassResponsibility: _cmd];
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (NSUInteger) sizeInBytes: (NSHashTable*)exclude
|
||||
{
|
||||
NSUInteger size = [super sizeInBytes: exclude];
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
NSUInteger count = [self count];
|
||||
|
||||
size += 3 * sizeof(void*) * count;
|
||||
if (count > 0)
|
||||
{
|
||||
NSAutoreleasePool *pool = [NSAutoreleasePool new];
|
||||
NSEnumerator *enumerator = [self keyEnumerator];
|
||||
NSObject *k;
|
||||
|
||||
while ((k = [enumerator nextObject]) != nil)
|
||||
{
|
||||
NSObject *o = [self objectForKey: k];
|
||||
|
||||
size += [k sizeInBytes: exclude] + [o sizeInBytes: exclude];
|
||||
}
|
||||
[pool release];
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#import "Foundation/NSAutoreleasePool.h"
|
||||
#import "Foundation/NSArray.h"
|
||||
#import "Foundation/NSException.h"
|
||||
#import "Foundation/NSHashTable.h"
|
||||
#import "Foundation/NSPortCoder.h"
|
||||
#import "Foundation/NSDistantObject.h"
|
||||
#import "Foundation/NSThread.h"
|
||||
|
@ -2607,3 +2608,24 @@ static id gs_weak_load(id obj)
|
|||
}
|
||||
@end
|
||||
|
||||
NSUInteger
|
||||
GSPrivateMemorySize(NSObject *self, NSHashTable *exclude)
|
||||
{
|
||||
if (0 == NSHashGet(exclude, self))
|
||||
{
|
||||
NSHashInsert(exclude, self);
|
||||
return class_getInstanceSize(object_getClass(self));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@implementation NSObject (MemorySize)
|
||||
+ (NSUInteger) sizeInBytes: (NSHashTable*)exclude
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
- (NSUInteger) sizeInBytes: (NSHashTable*)exclude
|
||||
{
|
||||
return GSPrivateMemorySize(self, exclude);
|
||||
}
|
||||
@end
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#import "common.h"
|
||||
#import "Foundation/NSArray.h"
|
||||
#import "Foundation/NSAutoreleasePool.h"
|
||||
#import "Foundation/NSSet.h"
|
||||
#import "Foundation/NSCoder.h"
|
||||
#import "Foundation/NSArray.h"
|
||||
|
@ -997,6 +998,32 @@ static Class NSMutableSet_concrete_class;
|
|||
[self subclassResponsibility: _cmd];
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (NSUInteger) sizeInBytes: (NSHashTable*)exclude
|
||||
{
|
||||
NSUInteger size = [super sizeInBytes: exclude];
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
NSUInteger count = [self count];
|
||||
|
||||
size += 3 * sizeof(void*) * count;
|
||||
if (count > 0)
|
||||
{
|
||||
NSAutoreleasePool *pool = [NSAutoreleasePool new];
|
||||
NSEnumerator *enumerator = [self objectEnumerator];
|
||||
NSObject *o;
|
||||
|
||||
while ((o = [enumerator nextObject]) != nil)
|
||||
{
|
||||
size += [o sizeInBytes: exclude];
|
||||
}
|
||||
[pool release];
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
|
|
@ -5923,6 +5923,17 @@ static NSFileManager *fm = nil;
|
|||
return GSPropertyListFromStringsFormat(self);
|
||||
}
|
||||
|
||||
- (NSUInteger) sizeInBytes: (NSHashTable*)exclude
|
||||
{
|
||||
NSUInteger size = [super sizeInBytes: exclude];
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
size += sizeof(unichar) * [self length];
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue