ObjFW  Check-in [bf0f10966f]

Overview
Comment:Add +[inheritInstanceMethodsFromClass:] to OFObject.

This allows something similar to multiple inheritance.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: bf0f10966f08e33795fa43a9ca3dbb21b004c0bb5d7d58acb2fe4e478c2b22e0
User & Date: js on 2011-07-29 21:54:36
Other Links: manifest | tags
Context
2011-07-30
02:14
Improve +[inheritInstanceMethodsFromClass:]. check-in: cace873874 user: js tags: trunk
2011-07-29
21:54
Add +[inheritInstanceMethodsFromClass:] to OFObject. check-in: bf0f10966f user: js tags: trunk
21:52
Fix a leak in OFIntrospection with the Apple runtime. check-in: 0708d6f152 user: js tags: trunk
Changes

Modified src/OFObject.h from [0bcf5ccb1b] to [250cefa1d6].

374
375
376
377
378
379
380



























381
382
383
384
385
386
387
 * \param selector The selector of the instance method to replace
 * \param class_ The class from which the new instance method should be taken
 * \return The old implementation
 */
+ (IMP)replaceInstanceMethod: (SEL)selector
	 withMethodFromClass: (Class)class_;




























/**
 * \brief Initializes an already allocated object.
 *
 * Derived classes may override this, but need to do self = [super init] before
 * they do any initialization themselves. init may never return nil, instead
 * an exception (for example OFInitializationFailed) should be thrown.
 *







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
 * \param selector The selector of the instance method to replace
 * \param class_ The class from which the new instance method should be taken
 * \return The old implementation
 */
+ (IMP)replaceInstanceMethod: (SEL)selector
	 withMethodFromClass: (Class)class_;

/**
 * \brief Adds an instance method to the class.
 *
 * If the method already exists, nothing is done and NO is returned. If you want
 * to change the implementation of a method, use
 * setImplementation:forInstanceMethod:.
 *
 * \param selector The selector for the new method
 * \param typeEncoding The type encoding for the new method
 * \param implementation The implementation for the new method
 * \return Whether the method has been added
 */
+ (BOOL)addInstanceMethod: (SEL)selector
	 withTypeEncoding: (const char*)typeEncoding
	   implementation: (IMP)implementation;

/**
 * \brief Adds all instance methods from the specified class to the class that
 *	  is the receiver.
 *
 * Existing methods will not be overriden, so that it behaves similar to normal
 * inheritance.
 *
 * \param class The class from which the instance methods should be inherited
 */
+ (void)inheritInstanceMethodsFromClass: (Class)class;

/**
 * \brief Initializes an already allocated object.
 *
 * Derived classes may override this, but need to do self = [super init] before
 * they do any initialization themselves. init may never return nil, instead
 * an exception (for example OFInitializationFailed) should be thrown.
 *

Modified src/OFObject.m from [51e0fb0c89] to [c64aa46779].

23
24
25
26
27
28
29


30
31
32
33
34
35
36
#include <string.h>

#include <unistd.h>

#include <assert.h>

#import "OFObject.h"


#import "OFAutoreleasePool.h"

#import "OFAllocFailedException.h"
#import "OFEnumerationMutationException.h"
#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFMemoryNotPartOfObjectException.h"







>
>







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <string.h>

#include <unistd.h>

#include <assert.h>

#import "OFObject.h"
#import "OFArray.h"
#import "OFIntrospection.h"
#import "OFAutoreleasePool.h"

#import "OFAllocFailedException.h"
#import "OFEnumerationMutationException.h"
#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFMemoryNotPartOfObjectException.h"
443
444
445
446
447
448
449






































450
451
452
453
454
455
456
						       selector: _cmd];

	newImp = [class instanceMethodForSelector: selector];

	return [self setImplementation: newImp
		     forInstanceMethod: selector];
}







































- init
{
	return self;
}

- (Class)class







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
						       selector: _cmd];

	newImp = [class instanceMethodForSelector: selector];

	return [self setImplementation: newImp
		     forInstanceMethod: selector];
}

+ (BOOL)addInstanceMethod: (SEL)selector
	 withTypeEncoding: (const char*)typeEncoding
	   implementation: (IMP)implementation
{
#if defined(OF_APPLE_RUNTIME) || defined(OF_GNU_RUNTIME)
	return class_addMethod(self, selector, implementation, typeEncoding);
#elif defined(OF_OLD_GNU_RUNTIME)
	@throw [OFNotImplementedException newWithClass: isa
					      selector: _cmd];
#endif
}

+ (void)inheritInstanceMethodsFromClass: (Class)class
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFIntrospection *introspection;
	OFMethod **cArray;
	size_t i, count;

	introspection = [OFIntrospection introspectionWithClass: class];
	cArray = [[introspection instanceMethods] cArray];
	count = [[introspection instanceMethods] count];

	for (i = 0; i < count; i++) {
		SEL selector;
		IMP implementation;

		selector = [cArray[i] selector];
		implementation = [class instanceMethodForSelector: selector];

		[self addInstanceMethod: selector
		       withTypeEncoding: [cArray[i] typeEncoding]
			 implementation: implementation];
	}

	[pool release];
}

- init
{
	return self;
}

- (Class)class