Created
February 20, 2013 21:34
-
-
Save OdNairy/4999836 to your computer and use it in GitHub Desktop.
NSObject source code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) 1999-2007 Apple Inc. All Rights Reserved. | |
* | |
* @APPLE_LICENSE_HEADER_START@ | |
* | |
* This file contains Original Code and/or Modifications of Original Code | |
* as defined in and that are subject to the Apple Public Source License | |
* Version 2.0 (the 'License'). You may not use this file except in | |
* compliance with the License. Please obtain a copy of the License at | |
* http://www.opensource.apple.com/apsl/ and read it before using this | |
* file. | |
* | |
* The Original Code and all software distributed under the License are | |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
* Please see the License for the specific language governing rights and | |
* limitations under the License. | |
* | |
* @APPLE_LICENSE_HEADER_END@ | |
*/ | |
/* | |
Object.m | |
Copyright 1988-1996 NeXT Software, Inc. | |
*/ | |
#if __OBJC2__ | |
#import "Object.h" | |
@implementation Object | |
+ initialize | |
{ | |
return self; | |
} | |
+ class | |
{ | |
return self; | |
} | |
@end | |
#else | |
#import <stdlib.h> | |
#import <stdarg.h> | |
#import <string.h> | |
#import <malloc/malloc.h> | |
#define OLD 1 | |
#import "Object.h" | |
#import "Protocol.h" | |
#import "objc-runtime.h" | |
#import "objc-auto.h" | |
// hack | |
extern void _objc_error(id, const char *, va_list); | |
// Error Messages | |
static const char | |
_errShouldHaveImp[] = "should have implemented the '%s' method.", | |
_errShouldNotImp[] = "should NOT have implemented the '%s' method.", | |
_errLeftUndone[] = "method '%s' not implemented", | |
_errBadSel[] = "method %s given invalid selector %s", | |
_errDoesntRecognize[] = "does not recognize selector %c%s"; | |
@implementation Object | |
+ initialize | |
{ | |
return self; | |
} | |
- awake | |
{ | |
return self; | |
} | |
+ poseAs: aFactory | |
{ | |
return class_poseAs(self, aFactory); | |
} | |
+ new | |
{ | |
id newObject = (*_alloc)((Class)self, 0); | |
Class metaClass = self->isa; | |
if (class_getVersion(metaClass) > 1) | |
return [newObject init]; | |
else | |
return newObject; | |
} | |
+ alloc | |
{ | |
return (*_zoneAlloc)((Class)self, 0, malloc_default_zone()); | |
} | |
+ allocFromZone:(void *) z | |
{ | |
return (*_zoneAlloc)((Class)self, 0, z); | |
} | |
- init | |
{ | |
return self; | |
} | |
- (const char *)name | |
{ | |
return class_getName(isa); | |
} | |
+ (const char *)name | |
{ | |
return class_getName((Class)self); | |
} | |
- (unsigned)hash | |
{ | |
return (unsigned)(((uintptr_t)self) >> 2); | |
} | |
- (BOOL)isEqual:anObject | |
{ | |
return anObject == self; | |
} | |
- free | |
{ | |
return (*_dealloc)(self); | |
} | |
+ free | |
{ | |
return nil; | |
} | |
- self | |
{ | |
return self; | |
} | |
- class | |
{ | |
return (id)isa; | |
} | |
+ class | |
{ | |
return self; | |
} | |
- (void *)zone | |
{ | |
void *z = malloc_zone_from_ptr(self); | |
return z ? z : malloc_default_zone(); | |
} | |
+ superclass | |
{ | |
return class_getSuperclass((Class)self); | |
} | |
- superclass | |
{ | |
return class_getSuperclass(isa); | |
} | |
+ (int) version | |
{ | |
return class_getVersion((Class)self); | |
} | |
+ setVersion: (int) aVersion | |
{ | |
class_setVersion((Class)self, aVersion); | |
return self; | |
} | |
- (BOOL)isKindOf:aClass | |
{ | |
register Class cls; | |
for (cls = isa; cls; cls = class_getSuperclass(cls)) | |
if (cls == (Class)aClass) | |
return YES; | |
return NO; | |
} | |
- (BOOL)isMemberOf:aClass | |
{ | |
return isa == (Class)aClass; | |
} | |
- (BOOL)isKindOfClassNamed:(const char *)aClassName | |
{ | |
register Class cls; | |
for (cls = isa; cls; cls = class_getSuperclass(cls)) | |
if (strcmp(aClassName, class_getName(cls)) == 0) | |
return YES; | |
return NO; | |
} | |
- (BOOL)isMemberOfClassNamed:(const char *)aClassName | |
{ | |
return strcmp(aClassName, class_getName(isa)) == 0; | |
} | |
+ (BOOL)instancesRespondTo:(SEL)aSelector | |
{ | |
return class_respondsToMethod((Class)self, aSelector); | |
} | |
- (BOOL)respondsTo:(SEL)aSelector | |
{ | |
return class_respondsToMethod(isa, aSelector); | |
} | |
- copy | |
{ | |
return [self copyFromZone: [self zone]]; | |
} | |
- copyFromZone:(void *)z | |
{ | |
return (*_zoneCopy)(self, 0, z); | |
} | |
- (IMP)methodFor:(SEL)aSelector | |
{ | |
return class_lookupMethod(isa, aSelector); | |
} | |
+ (IMP)instanceMethodFor:(SEL)aSelector | |
{ | |
return class_lookupMethod(self, aSelector); | |
} | |
- perform:(SEL)aSelector | |
{ | |
if (aSelector) | |
return objc_msgSend(self, aSelector); | |
else | |
return [self error:_errBadSel, sel_getName(_cmd), aSelector]; | |
} | |
- perform:(SEL)aSelector with:anObject | |
{ | |
if (aSelector) | |
return objc_msgSend(self, aSelector, anObject); | |
else | |
return [self error:_errBadSel, sel_getName(_cmd), aSelector]; | |
} | |
- perform:(SEL)aSelector with:obj1 with:obj2 | |
{ | |
if (aSelector) | |
return objc_msgSend(self, aSelector, obj1, obj2); | |
else | |
return [self error:_errBadSel, sel_getName(_cmd), aSelector]; | |
} | |
- subclassResponsibility:(SEL)aSelector | |
{ | |
return [self error:_errShouldHaveImp, sel_getName(aSelector)]; | |
} | |
- notImplemented:(SEL)aSelector | |
{ | |
return [self error:_errLeftUndone, sel_getName(aSelector)]; | |
} | |
- doesNotRecognize:(SEL)aMessage | |
{ | |
return [self error:_errDoesntRecognize, | |
class_isMetaClass(isa) ? '+' : '-', sel_getName(aMessage)]; | |
} | |
- error:(const char *)aCStr, ... | |
{ | |
va_list ap; | |
va_start(ap,aCStr); | |
(*_error)(self, aCStr, ap); | |
_objc_error (self, aCStr, ap); /* In case (*_error)() returns. */ | |
va_end(ap); | |
return nil; | |
} | |
- (void) printForDebugger:(void *)stream | |
{ | |
} | |
- write:(void *) stream | |
{ | |
return self; | |
} | |
- read:(void *) stream | |
{ | |
return self; | |
} | |
- forward: (SEL) sel : (marg_list) args | |
{ | |
return [self doesNotRecognize: sel]; | |
} | |
/* this method is not part of the published API */ | |
- (unsigned)methodArgSize:(SEL)sel | |
{ | |
Method method = class_getInstanceMethod((Class)isa, sel); | |
if (! method) return 0; | |
return method_getSizeOfArguments(method); | |
} | |
- performv: (SEL) sel : (marg_list) args | |
{ | |
unsigned size; | |
// Messages to nil object always return nil | |
if (! self) return nil; | |
// Calculate size of the marg_list from the method's | |
// signature. This looks for the method in self | |
// and its superclasses. | |
size = [self methodArgSize: sel]; | |
// If neither self nor its superclasses implement | |
// it, forward the message because self might know | |
// someone who does. This is a "chained" forward... | |
if (! size) return [self forward: sel: args]; | |
// Message self with the specified selector and arguments | |
return objc_msgSendv (self, sel, size, args); | |
} | |
/* Testing protocol conformance */ | |
- (BOOL) conformsTo: (Protocol *)aProtocolObj | |
{ | |
return [(id)isa conformsTo:aProtocolObj]; | |
} | |
+ (BOOL) conformsTo: (Protocol *)aProtocolObj | |
{ | |
Class class; | |
for (class = self; class; class = class_getSuperclass(class)) | |
{ | |
if (class_conformsToProtocol(class, aProtocolObj)) return YES; | |
} | |
return NO; | |
} | |
/* Looking up information for a method */ | |
- (struct objc_method_description *) descriptionForMethod:(SEL)aSelector | |
{ | |
Class cls; | |
struct objc_method_description *m; | |
/* Look in the protocols first. */ | |
for (cls = isa; cls; cls = cls->super_class) | |
{ | |
if (cls->isa->version >= 3) | |
{ | |
struct objc_protocol_list *protocols = cls->protocols; | |
while (protocols) | |
{ | |
int i; | |
for (i = 0; i < protocols->count; i++) | |
{ | |
Protocol *p = protocols->list[i]; | |
if (class_isMetaClass(cls)) | |
m = [p descriptionForClassMethod:aSelector]; | |
else | |
m = [p descriptionForInstanceMethod:aSelector]; | |
if (m) { | |
return m; | |
} | |
} | |
if (cls->isa->version <= 4) | |
break; | |
protocols = protocols->next; | |
} | |
} | |
} | |
/* Then try the class implementations. */ | |
for (cls = isa; cls; cls = cls->super_class) { | |
void *iterator = 0; | |
int i; | |
struct objc_method_list *mlist; | |
while ( (mlist = class_nextMethodList( cls, &iterator )) ) { | |
for (i = 0; i < mlist->method_count; i++) | |
if (mlist->method_list[i].method_name == aSelector) { | |
struct objc_method_description *m; | |
m = (struct objc_method_description *)&mlist->method_list[i]; | |
return m; | |
} | |
} | |
} | |
return 0; | |
} | |
+ (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSelector | |
{ | |
Class cls; | |
/* Look in the protocols first. */ | |
for (cls = self; cls; cls = cls->super_class) | |
{ | |
if (cls->isa->version >= 3) | |
{ | |
struct objc_protocol_list *protocols = cls->protocols; | |
while (protocols) | |
{ | |
int i; | |
for (i = 0; i < protocols->count; i++) | |
{ | |
Protocol *p = protocols->list[i]; | |
struct objc_method_description *m; | |
if ((m = [p descriptionForInstanceMethod:aSelector])) | |
return m; | |
} | |
if (cls->isa->version <= 4) | |
break; | |
protocols = protocols->next; | |
} | |
} | |
} | |
/* Then try the class implementations. */ | |
for (cls = self; cls; cls = cls->super_class) { | |
void *iterator = 0; | |
int i; | |
struct objc_method_list *mlist; | |
while ( (mlist = class_nextMethodList( cls, &iterator )) ) { | |
for (i = 0; i < mlist->method_count; i++) | |
if (mlist->method_list[i].method_name == aSelector) { | |
struct objc_method_description *m; | |
m = (struct objc_method_description *)&mlist->method_list[i]; | |
return m; | |
} | |
} | |
} | |
return 0; | |
} | |
/* Obsolete methods (for binary compatibility only). */ | |
+ superClass | |
{ | |
return [self superclass]; | |
} | |
- superClass | |
{ | |
return [self superclass]; | |
} | |
- (BOOL)isKindOfGivenName:(const char *)aClassName | |
{ | |
return [self isKindOfClassNamed: aClassName]; | |
} | |
- (BOOL)isMemberOfGivenName:(const char *)aClassName | |
{ | |
return [self isMemberOfClassNamed: aClassName]; | |
} | |
- (struct objc_method_description *) methodDescFor:(SEL)aSelector | |
{ | |
return [self descriptionForMethod: aSelector]; | |
} | |
+ (struct objc_method_description *) instanceMethodDescFor:(SEL)aSelector | |
{ | |
return [self descriptionForInstanceMethod: aSelector]; | |
} | |
- findClass:(const char *)aClassName | |
{ | |
return objc_lookUpClass(aClassName); | |
} | |
- shouldNotImplement:(SEL)aSelector | |
{ | |
return [self error:_errShouldNotImp, sel_getName(aSelector)]; | |
} | |
@end | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment