Object.m
上传用户:shenzhenrh
上传日期:2013-05-12
资源大小:2904k
文件大小:8k
- /* The implementation of class Object for Objective-C.
- Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
- This file is part of GNU CC.
- GNU CC 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, or (at your option) any
- later version.
- GNU CC 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 General Public
- License for more details.
- You should have received a copy of the GNU General Public License
- along with GNU CC; see the file COPYING. If not, write to
- the Free Software Foundation, 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
- /* As a special exception, if you link this library with files compiled
- with GCC to produce an executable, this does not cause the resulting
- executable to be covered by the GNU General Public License. This
- exception does not however invalidate any other reasons why the
- executable file might be covered by the GNU General Public License. */
- #include "objc/Object.h"
- #include "objc/Protocol.h"
- #include "objc/objc-api.h"
- #include <stdarg.h>
- #include <string.h>
- extern int errno;
- #define MAX_CLASS_NAME_LEN 256
- @implementation Object
- + initialize
- {
- return self;
- }
- - init
- {
- return self;
- }
- + new
- {
- return [[self alloc] init];
- }
- + alloc
- {
- return class_create_instance (self);
- }
- - free
- {
- return object_dispose (self);
- }
- - copy
- {
- return [[self shallowCopy] deepen];
- }
- - shallowCopy
- {
- return object_copy(self);
- }
- - deepen
- {
- return self;
- }
- - deepCopy
- {
- return [self copy];
- }
- - (Class)class
- {
- return object_get_class (self);
- }
- - (Class)superClass
- {
- return object_get_super_class (self);
- }
- - (MetaClass)metaClass
- {
- return object_get_meta_class (self);
- }
- - (const char *)name
- {
- return object_get_class_name (self);
- }
- - self
- {
- return self;
- }
- - (unsigned int)hash
- {
- return (size_t) self;
- }
- - (BOOL)isEqual:anObject
- {
- return self == anObject;
- }
- - (int)compare:anotherObject;
- {
- if ([self isEqual: anotherObject])
- return 0;
- // Ordering objects by their address is pretty useless,
- // so subclasses should override this is some useful way.
- else if (self > anotherObject)
- return 1;
- else
- return -1;
- }
- - (BOOL)isMetaClass
- {
- return NO;
- }
- - (BOOL)isClass
- {
- return object_is_class (self);
- }
- - (BOOL)isInstance
- {
- return object_is_instance (self);
- }
- - (BOOL)isKindOf: (Class)aClassObject
- {
- Class class;
- for (class = self->isa; class != Nil; class = class_get_super_class (class))
- if (class == aClassObject)
- return YES;
- return NO;
- }
- - (BOOL)isMemberOf:(Class)aClassObject
- {
- return self->isa==aClassObject;
- }
- - (BOOL)isKindOfClassNamed:(const char *)aClassName
- {
- Class class;
- if (aClassName != NULL)
- for (class = self->isa;
- class != Nil;
- class = class_get_super_class (class))
- if (!strcmp (class_get_class_name (class), aClassName))
- return YES;
- return NO;
- }
- - (BOOL)isMemberOfClassNamed:(const char *)aClassName
- {
- return ((aClassName != NULL)
- && !strcmp (class_get_class_name (self->isa), aClassName));
- }
- + (BOOL)instancesRespondTo:(SEL)aSel
- {
- return class_get_instance_method (self, aSel) != METHOD_NULL;
- }
- - (BOOL)respondsTo:(SEL)aSel
- {
- return ((object_is_instance (self)
- ? class_get_instance_method (self->isa, aSel)
- : class_get_class_method (self->isa, aSel)) != METHOD_NULL);
- }
- + (IMP)instanceMethodFor:(SEL)aSel
- {
- return method_get_imp (class_get_instance_method (self, aSel));
- }
- // Indicates if the receiving class or instance conforms to the given protocol
- // not usually overridden by subclasses
- //
- // Modified 9/5/94 to always search the class object's protocol list, rather
- // than the meta class.
- + (BOOL) conformsTo: (Protocol*)aProtocol
- {
- int i;
- struct objc_protocol_list* proto_list;
- id parent;
- for (proto_list = ((Class) self)->protocols;
- proto_list; proto_list = proto_list->next)
- {
- for (i=0; i < proto_list->count; i++)
- {
- if ([proto_list->list[i] conformsTo: aProtocol])
- return YES;
- }
- }
- if ((parent = [self superClass]))
- return [parent conformsTo: aProtocol];
- else
- return NO;
- }
- - (BOOL) conformsTo: (Protocol*)aProtocol
- {
- return [[self class] conformsTo:aProtocol];
- }
- - (IMP)methodFor:(SEL)aSel
- {
- return (method_get_imp (object_is_instance(self)
- ? class_get_instance_method (self->isa, aSel)
- : class_get_class_method (self->isa, aSel)));
- }
- + (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel
- {
- return ((struct objc_method_description *)
- class_get_instance_method (self, aSel));
- }
- - (struct objc_method_description *)descriptionForMethod:(SEL)aSel
- {
- return ((struct objc_method_description *)
- (object_is_instance (self)
- ? class_get_instance_method (self->isa, aSel)
- : class_get_class_method (self->isa, aSel)));
- }
- - perform:(SEL)aSel
- {
- IMP msg = objc_msg_lookup(self, aSel);
- if (!msg)
- return [self error:"invalid selector passed to %s", sel_get_name (_cmd)];
- return (*msg) (self, aSel);
- }
- - perform:(SEL)aSel with:anObject
- {
- IMP msg = objc_msg_lookup (self, aSel);
- if (!msg)
- return [self error:"invalid selector passed to %s", sel_get_name (_cmd)];
- return (*msg) (self, aSel, anObject);
- }
- - perform:(SEL)aSel with:anObject1 with:anObject2
- {
- IMP msg = objc_msg_lookup(self, aSel);
- if (!msg)
- return [self error:"invalid selector passed to %s", sel_get_name (_cmd)];
- return (*msg) (self, aSel, anObject1, anObject2);
- }
- - (retval_t)forward:(SEL)aSel :(arglist_t)argFrame
- {
- return (retval_t) [self doesNotRecognize: aSel];
- }
- - (retval_t)performv:(SEL)aSel :(arglist_t)argFrame
- {
- return objc_msg_sendv (self, aSel, argFrame);
- }
- + poseAs:(Class)aClassObject
- {
- return class_pose_as (self, aClassObject);
- }
- - (Class)transmuteClassTo:(Class)aClassObject
- {
- if (object_is_instance (self))
- if (class_is_class (aClassObject))
- if (class_get_instance_size (aClassObject) == class_get_instance_size(isa))
- if ([self isKindOf:aClassObject])
- {
- Class old_isa = isa;
- isa = aClassObject;
- return old_isa;
- }
- return nil;
- }
- - subclassResponsibility:(SEL)aSel
- {
- return [self error:"subclass should override %s", sel_get_name(aSel)];
- }
- - notImplemented:(SEL)aSel
- {
- return [self error:"method %s not implemented", sel_get_name(aSel)];
- }
- - shouldNotImplement:(SEL)aSel
- {
- return [self error:"%s should not implement %s",
- object_get_class_name(self), sel_get_name(aSel)];
- }
- - doesNotRecognize:(SEL)aSel
- {
- return [self error:"%s does not recognize %s",
- object_get_class_name(self), sel_get_name(aSel)];
- }
- #ifdef __alpha__
- extern size_t strlen(const char*);
- #endif
- - error:(const char *)aString, ...
- {
- #define FMT "error: %s (%s)n%sn"
- char fmt[(strlen ((char*) FMT)
- + strlen ((char*) object_get_class_name (self))
- + ((aString != NULL) ? strlen ((char*) aString) : 0) + 8)];
- va_list ap;
- sprintf(fmt, FMT, object_get_class_name(self),
- object_is_instance (self) ? "instance" : "class",
- (aString != NULL) ? aString : "");
- va_start (ap, aString);
- objc_verror (self, OBJC_ERR_UNKNOWN, fmt, ap);
- va_end (ap);
- return nil;
- #undef FMT
- }
- + (int)version
- {
- return class_get_version (self);
- }
- + setVersion:(int)aVersion
- {
- class_set_version (self, aVersion);
- return self;
- }
- + (int)streamVersion: (TypedStream*)aStream
- {
- if (aStream->mode == OBJC_READONLY)
- return objc_get_stream_class_version (aStream, self);
- else
- return class_get_version (self);
- }
- // These are used to write or read the instance variables
- // declared in this particular part of the object. Subclasses
- // should extend these, by calling [super read/write: aStream]
- // before doing their own archiving. These methods are private, in
- // the sense that they should only be called from subclasses.
- - read: (TypedStream*)aStream
- {
- // [super read: aStream];
- return self;
- }
- - write: (TypedStream*)aStream
- {
- // [super write: aStream];
- return self;
- }
- - awake
- {
- // [super awake];
- return self;
- }
- @end