Skip to content

Instantly share code, notes, and snippets.

@OdNairy
Created February 20, 2013 21:34
Show Gist options
  • Save OdNairy/4999836 to your computer and use it in GitHub Desktop.
Save OdNairy/4999836 to your computer and use it in GitHub Desktop.
NSObject source code
/*
* 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