Object.m
上传用户:shenzhenrh
上传日期:2013-05-12
资源大小:2904k
文件大小:8k
源码类别:

信息检索与抽取

开发平台:

Unix_Linux

  1. /* The implementation of class Object for Objective-C.
  2.    Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
  3. This file is part of GNU CC.
  4. GNU CC is free software; you can redistribute it and/or modify it
  5. under the terms of the GNU General Public License as published by the
  6. Free Software Foundation; either version 2, or (at your option) any
  7. later version.
  8. GNU CC is distributed in the hope that it will be useful, but WITHOUT
  9. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
  11. License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU CC; see the file COPYING.  If not, write to
  14. the Free Software Foundation, 59 Temple Place - Suite 330,
  15. Boston, MA 02111-1307, USA.  */
  16. /* As a special exception, if you link this library with files compiled
  17.    with GCC to produce an executable, this does not cause the resulting
  18.    executable to be covered by the GNU General Public License.  This
  19.    exception does not however invalidate any other reasons why the
  20.    executable file might be covered by the GNU General Public License. */
  21. #include "objc/Object.h"
  22. #include "objc/Protocol.h"
  23. #include "objc/objc-api.h"
  24. #include <stdarg.h>
  25. #include <string.h>
  26. extern int errno;
  27. #define MAX_CLASS_NAME_LEN 256
  28. @implementation Object
  29. + initialize
  30. {
  31.   return self;
  32. }
  33. - init
  34. {
  35.   return self;
  36. }
  37. + new
  38. {
  39.   return [[self alloc] init];
  40. }
  41. + alloc
  42. {
  43.   return class_create_instance (self);
  44. }
  45. - free
  46. {
  47.   return object_dispose (self);
  48. }
  49. - copy
  50. {
  51.   return [[self shallowCopy] deepen];
  52. }
  53. - shallowCopy
  54. {
  55.   return object_copy(self);
  56. }
  57. - deepen
  58. {
  59.   return self;
  60. }
  61. - deepCopy
  62. {
  63.   return [self copy];
  64. }
  65. - (Class)class
  66. {
  67.   return object_get_class (self);
  68. }
  69. - (Class)superClass
  70. {
  71.   return object_get_super_class (self);
  72. }
  73. - (MetaClass)metaClass
  74. {
  75.   return object_get_meta_class (self);
  76. }
  77. - (const char *)name
  78. {
  79.   return object_get_class_name (self);
  80. }
  81. - self
  82. {
  83.   return self;
  84. }
  85. - (unsigned int)hash
  86. {
  87.   return (size_t) self;
  88. }
  89. - (BOOL)isEqual:anObject
  90. {
  91.   return self == anObject;
  92. }
  93. - (int)compare:anotherObject;
  94. {
  95.   if ([self isEqual: anotherObject])
  96.     return 0;
  97.   // Ordering objects by their address is pretty useless, 
  98.   // so subclasses should override this is some useful way.
  99.   else if (self > anotherObject)
  100.     return 1;
  101.   else 
  102.     return -1;
  103. }
  104. - (BOOL)isMetaClass
  105. {
  106.   return NO;
  107. }
  108. - (BOOL)isClass
  109. {
  110.   return object_is_class (self);
  111. }
  112. - (BOOL)isInstance
  113. {
  114.   return object_is_instance (self);
  115. }
  116. - (BOOL)isKindOf: (Class)aClassObject
  117. {
  118.   Class class;
  119.   for (class = self->isa; class != Nil; class = class_get_super_class (class))
  120.     if (class == aClassObject)
  121.       return YES;
  122.   return NO;
  123. }
  124. - (BOOL)isMemberOf:(Class)aClassObject
  125. {
  126.   return self->isa==aClassObject;
  127. }
  128. - (BOOL)isKindOfClassNamed:(const char *)aClassName
  129. {
  130.   Class class;
  131.   if (aClassName != NULL)
  132.     for (class = self->isa;
  133.          class != Nil;
  134.          class = class_get_super_class (class))
  135.       if (!strcmp (class_get_class_name (class), aClassName))
  136.         return YES;
  137.   return NO;
  138. }
  139. - (BOOL)isMemberOfClassNamed:(const char *)aClassName
  140. {
  141.   return ((aClassName != NULL)
  142.           && !strcmp (class_get_class_name (self->isa), aClassName));
  143. }
  144. + (BOOL)instancesRespondTo:(SEL)aSel
  145. {
  146.   return class_get_instance_method (self, aSel) != METHOD_NULL;
  147. }
  148. - (BOOL)respondsTo:(SEL)aSel
  149. {
  150.   return ((object_is_instance (self)
  151.            ? class_get_instance_method (self->isa, aSel)
  152.            : class_get_class_method (self->isa, aSel)) != METHOD_NULL);
  153. }
  154. + (IMP)instanceMethodFor:(SEL)aSel
  155. {
  156.   return method_get_imp (class_get_instance_method (self, aSel));
  157. }
  158. // Indicates if the receiving class or instance conforms to the given protocol
  159. // not usually overridden by subclasses
  160. //
  161. // Modified 9/5/94 to always search the class object's protocol list, rather
  162. // than the meta class.
  163. + (BOOL) conformsTo: (Protocol*)aProtocol
  164. {
  165.   int i;
  166.   struct objc_protocol_list* proto_list;
  167.   id parent;
  168.   for (proto_list = ((Class) self)->protocols;
  169.        proto_list; proto_list = proto_list->next)
  170.     {
  171.       for (i=0; i < proto_list->count; i++)
  172.       {
  173.         if ([proto_list->list[i] conformsTo: aProtocol])
  174.           return YES;
  175.       }
  176.     }
  177.   if ((parent = [self superClass]))
  178.     return [parent conformsTo: aProtocol];
  179.   else
  180.     return NO;
  181. }
  182. - (BOOL) conformsTo: (Protocol*)aProtocol
  183. {
  184.   return [[self class] conformsTo:aProtocol];
  185. }
  186. - (IMP)methodFor:(SEL)aSel
  187. {
  188.   return (method_get_imp (object_is_instance(self)
  189.                          ? class_get_instance_method (self->isa, aSel)
  190.                          : class_get_class_method (self->isa, aSel)));
  191. }
  192. + (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel
  193. {
  194.   return ((struct objc_method_description *)
  195.            class_get_instance_method (self, aSel));
  196. }
  197. - (struct objc_method_description *)descriptionForMethod:(SEL)aSel
  198. {
  199.   return ((struct objc_method_description *)
  200.            (object_is_instance (self)
  201.             ? class_get_instance_method (self->isa, aSel)
  202.             : class_get_class_method (self->isa, aSel)));
  203. }
  204. - perform:(SEL)aSel
  205. {
  206.   IMP msg = objc_msg_lookup(self, aSel);
  207.   if (!msg)
  208.     return [self error:"invalid selector passed to %s", sel_get_name (_cmd)];
  209.   return (*msg) (self, aSel);
  210. }
  211. - perform:(SEL)aSel with:anObject
  212. {
  213.   IMP msg = objc_msg_lookup (self, aSel);
  214.   if (!msg)
  215.     return [self error:"invalid selector passed to %s", sel_get_name (_cmd)];
  216.   return (*msg) (self, aSel, anObject);
  217. }
  218. - perform:(SEL)aSel with:anObject1 with:anObject2
  219. {
  220.   IMP msg = objc_msg_lookup(self, aSel);
  221.   if (!msg)
  222.     return [self error:"invalid selector passed to %s", sel_get_name (_cmd)];
  223.   return (*msg) (self, aSel, anObject1, anObject2);
  224. }
  225. - (retval_t)forward:(SEL)aSel :(arglist_t)argFrame
  226. {
  227.   return (retval_t) [self doesNotRecognize: aSel];
  228. }
  229. - (retval_t)performv:(SEL)aSel :(arglist_t)argFrame
  230. {
  231.   return objc_msg_sendv (self, aSel, argFrame);
  232. }
  233. + poseAs:(Class)aClassObject
  234. {
  235.   return class_pose_as (self, aClassObject);
  236. }
  237. - (Class)transmuteClassTo:(Class)aClassObject
  238. {
  239.   if (object_is_instance (self))
  240.     if (class_is_class (aClassObject))
  241.       if (class_get_instance_size (aClassObject) == class_get_instance_size(isa))
  242.         if ([self isKindOf:aClassObject])
  243.           {
  244.             Class old_isa = isa;
  245.             isa = aClassObject;
  246.             return old_isa;
  247.           }
  248.   return nil;
  249. }
  250. - subclassResponsibility:(SEL)aSel
  251. {
  252.   return [self error:"subclass should override %s", sel_get_name(aSel)];
  253. }
  254. - notImplemented:(SEL)aSel
  255. {
  256.   return [self error:"method %s not implemented", sel_get_name(aSel)];
  257. }
  258. - shouldNotImplement:(SEL)aSel
  259. {
  260.   return [self error:"%s should not implement %s", 
  261.              object_get_class_name(self), sel_get_name(aSel)];
  262. }
  263. - doesNotRecognize:(SEL)aSel
  264. {
  265.   return [self error:"%s does not recognize %s",
  266.                      object_get_class_name(self), sel_get_name(aSel)];
  267. }
  268. #ifdef __alpha__
  269. extern size_t strlen(const char*);
  270. #endif
  271. - error:(const char *)aString, ...
  272. {
  273. #define FMT "error: %s (%s)n%sn"
  274.   char fmt[(strlen ((char*) FMT)
  275.             + strlen ((char*) object_get_class_name (self))
  276.             + ((aString != NULL) ? strlen ((char*) aString) : 0) + 8)];
  277.   va_list ap;
  278.   sprintf(fmt, FMT, object_get_class_name(self),
  279.                     object_is_instance (self) ? "instance" : "class",
  280.                     (aString != NULL) ? aString : "");
  281.   va_start (ap, aString);
  282.   objc_verror (self, OBJC_ERR_UNKNOWN, fmt, ap);
  283.   va_end (ap);
  284.   return nil;
  285. #undef FMT
  286. }
  287. + (int)version
  288. {
  289.   return class_get_version (self);
  290. }
  291. + setVersion:(int)aVersion
  292. {
  293.   class_set_version (self, aVersion);
  294.   return self;
  295. }
  296. + (int)streamVersion: (TypedStream*)aStream
  297. {
  298.   if (aStream->mode == OBJC_READONLY)
  299.     return objc_get_stream_class_version (aStream, self);
  300.   else
  301.     return class_get_version (self);
  302. }
  303. // These are used to write or read the instance variables 
  304. // declared in this particular part of the object.  Subclasses
  305. // should extend these, by calling [super read/write: aStream]
  306. // before doing their own archiving.  These methods are private, in
  307. // the sense that they should only be called from subclasses.
  308. - read: (TypedStream*)aStream
  309. {
  310.   // [super read: aStream];  
  311.   return self;
  312. }
  313. - write: (TypedStream*)aStream
  314. {
  315.   // [super write: aStream];
  316.   return self;
  317. }
  318. - awake
  319. {
  320.   // [super awake];
  321.   return self;
  322. }
  323. @end