![]() |
API 0.9.5
|
00001 /* 00002 * CPObject.j 00003 * Foundation 00004 * 00005 * Created by Francisco Tolmasky. 00006 * Copyright 2008, 280 North, Inc. 00007 * 00008 * This library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * This library is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 00064 @implementation CPObject 00065 { 00066 Class isa; 00067 } 00068 00069 + (void)load 00070 { 00071 } 00072 00073 + (void)initialize 00074 { 00075 // CPLog("calling initialize "+self.name); 00076 } 00077 00082 + (id)new 00083 { 00084 return [[self alloc] init]; 00085 } 00086 00090 + (id)alloc 00091 { 00092 // CPLog("calling alloc on " + self.name + "."); 00093 return class_createInstance(self); 00094 } 00095 00096 + (id)allocWithCoder:(CPCoder)aCoder 00097 { 00098 return [self alloc]; 00099 } 00100 00105 - (id)init 00106 { 00107 return self; 00108 } 00109 00114 - (id)copy 00115 { 00116 return self; 00117 } 00118 00123 - (id)mutableCopy 00124 { 00125 return [self copy]; 00126 } 00127 00131 - (void)dealloc 00132 { 00133 } 00134 00135 // Identifying classes 00139 + (Class)class 00140 { 00141 return self; 00142 } 00143 00147 - (Class)class 00148 { 00149 return isa; 00150 } 00151 00155 + (Class)superclass 00156 { 00157 return super_class; 00158 } 00159 00164 + (BOOL)isSubclassOfClass:(Class)aClass 00165 { 00166 var theClass = self; 00167 00168 for (; theClass; theClass = theClass.super_class) 00169 if (theClass === aClass) 00170 return YES; 00171 00172 return NO; 00173 } 00174 00179 - (BOOL)isKindOfClass:(Class)aClass 00180 { 00181 return [isa isSubclassOfClass:aClass]; 00182 } 00183 00184 + (BOOL)isKindOfClass:(Class)aClass 00185 { 00186 return [self isSubclassOfClass:aClass]; 00187 } 00188 00193 - (BOOL)isMemberOfClass:(Class)aClass 00194 { 00195 return self.isa === aClass; 00196 } 00197 00198 + (BOOL)isMemberOfClass:(Class)aClass 00199 { 00200 return self === aClass; 00201 } 00202 00207 - (BOOL)isProxy 00208 { 00209 return NO; 00210 } 00211 00212 // Testing class functionality 00218 + (BOOL)instancesRespondToSelector:(SEL)aSelector 00219 { 00220 return !!class_getInstanceMethod(self, aSelector); 00221 } 00222 00228 - (BOOL)respondsToSelector:(SEL)aSelector 00229 { 00230 // isa is isa.isa in class case. 00231 return !!class_getInstanceMethod(isa, aSelector); 00232 } 00233 00239 - (BOOL)implementsSelector:(SEL)aSelector 00240 { 00241 var methods = class_copyMethodList(isa), 00242 count = methods.length; 00243 00244 while (count--) 00245 if (method_getName(methods[count]) === aSelector) 00246 return YES; 00247 00248 return NO; 00249 } 00250 00251 // Obtaining method information 00252 00258 - (IMP)methodForSelector:(SEL)aSelector 00259 { 00260 return class_getMethodImplementation(isa, aSelector); 00261 } 00262 00268 + (IMP)instanceMethodForSelector:(SEL)aSelector 00269 { 00270 return class_getMethodImplementation(self, aSelector); 00271 } 00272 00278 - (CPMethodSignature)methodSignatureForSelector:(SEL)aSelector 00279 { 00280 // FIXME: We need to implement method signatures. 00281 return nil; 00282 } 00283 00284 // Describing objects 00288 - (CPString)description 00289 { 00290 return "<" + class_getName(isa) + " 0x" + [CPString stringWithHash:[self UID]] + ">"; 00291 } 00292 00293 + (CPString)description 00294 { 00295 return class_getName(isa); 00296 } 00297 00298 // Sending Messages 00304 - (id)performSelector:(SEL)aSelector 00305 { 00306 return objj_msgSend(self, aSelector); 00307 } 00308 00315 - (id)performSelector:(SEL)aSelector withObject:(id)anObject 00316 { 00317 return objj_msgSend(self, aSelector, anObject); 00318 } 00319 00327 - (id)performSelector:(SEL)aSelector withObject:(id)anObject withObject:(id)anotherObject 00328 { 00329 return objj_msgSend(self, aSelector, anObject, anotherObject); 00330 } 00331 00332 - (id)forwardingTargetForSelector:(SEL)aSelector 00333 { 00334 return nil; 00335 } 00336 00337 // Forwarding Messages 00344 - (void)forwardInvocation:(CPInvocation)anInvocation 00345 { 00346 [self doesNotRecognizeSelector:[anInvocation selector]]; 00347 } 00348 00349 // Error Handling 00355 - (void)doesNotRecognizeSelector:(SEL)aSelector 00356 { 00357 [CPException raise:CPInvalidArgumentException reason: 00358 (class_isMetaClass(isa) ? "+" : "-") + " [" + [self className] + " " + aSelector + "] unrecognized selector sent to " + 00359 (class_isMetaClass(isa) ? "class " + class_getName(isa) : "instance 0x" + [CPString stringWithHash:[self UID]])]; 00360 } 00361 00362 // Archiving 00371 - (id)awakeAfterUsingCoder:(CPCoder)aCoder 00372 { 00373 return self; 00374 } 00375 00380 - (Class)classForKeyedArchiver 00381 { 00382 return [self classForCoder]; 00383 } 00384 00389 - (Class)classForCoder 00390 { 00391 return [self class]; 00392 } 00393 00399 - (id)replacementObjectForArchiver:(CPArchiver)anArchiver 00400 { 00401 return [self replacementObjectForCoder:anArchiver]; 00402 } 00403 00409 - (id)replacementObjectForKeyedArchiver:(CPKeyedArchiver)anArchiver 00410 { 00411 return [self replacementObjectForCoder:anArchiver]; 00412 } 00413 00419 - (id)replacementObjectForCoder:(CPCoder)aCoder 00420 { 00421 return self; 00422 } 00423 00428 + (void)setVersion:(int)aVersion 00429 { 00430 class_setVersion(self, aVersion); 00431 } 00432 00436 + (int)version 00437 { 00438 return class_getVersion(self); 00439 } 00440 00441 // Scripting (?) 00445 - (CPString)className 00446 { 00447 // FIXME: Why doesn't this work in KVO??? 00448 // return class_getName([self class]); 00449 return isa.name; 00450 } 00451 00452 // Extras 00457 - (id)autorelease 00458 { 00459 return self; 00460 } 00461 00465 - (unsigned)hash 00466 { 00467 return [self UID]; 00468 } 00469 00470 - (CPString)UID 00471 { 00472 if (typeof self._UID === "undefined") 00473 self._UID = objj_generateObjectUID(); 00474 00475 return _UID + ""; 00476 } 00477 00482 - (BOOL)isEqual:(id)anObject 00483 { 00484 return self === anObject || [self UID] === [anObject UID]; 00485 } 00486 00491 - (id)retain 00492 { 00493 return self; 00494 } 00495 00499 - (void)release 00500 { 00501 } 00502 00506 - (id)self 00507 { 00508 return self; 00509 } 00510 00514 - (Class)superclass 00515 { 00516 return isa.super_class; 00517 } 00518 00519 @end