ãªããªããžã§ã¯ãå šäœãäœæããã¡ã¢ãªãå²ãåœãŠãéåžžã®å°ããªæŽæ°ãå¿ èŠãªå Žåã¯ããããããã«ããã®ã§ããããïŒ ã¢ããã«ãããèããŸããããªããªããNSNumberã¯ãªããžã§ã¯ãã§ã¯ãªãããšãå€ãããã®ãã€ã³ã¿ãŒã®åŸãã«ã¯é ãããŠããããã§ã...空èã§ãã
ãããã©ããªããããããŠããŒã¯ããããã€ã³ã¿ãŒããããšã©ãé¢ä¿ãããã«èå³ããããªããcatãžããããïŒ
å°ãã®ãã€ã³ã¿ãŒèª¿æŽçè«
ãã€ã³ã¿ã¯éåžžã®intã§ãããã·ã¹ãã ãã¡ã¢ãªå ã®ã¢ãã¬ã¹ãååŸããããšã¯èª°ããç¥ã£ãŠããŸãã ãªããžã§ã¯ããžã®ãã€ã³ã¿ãŒãå«ã倿°ã¯ã0x7f84a41000c0ãšãã圢åŒã®å€ãæã€intã§ãã ããã€ã³ãã£ã³ã°ãã®æ¬è³ªã¯ãããã°ã©ã ã§ã®äœ¿ç𿹿³ã«ãããŸãã Cã§ã¯ãåçŽãªãã£ã¹ãã«ãã£ãŠãã€ã³ã¿ãŒã®intå€ãååŸã§ããŸãã
void *somePointer = ...; uintptr_t pointerIntegerValue = (uintptr_t)somePointer;
ïŒ uintptr_tã¯ãæŽæ°ãä¿æããã®ã«ååãªå€§ããã®æŽæ°ã®æšæºé åtypdefã§ããããã¯ããã©ãããã©ãŒã ã«ãã£ãŠãã€ã³ã¿ãŒã®ãµã€ãºãç°ãªãããå¿ èŠã§ãïŒ
ã»ãšãã©ãã¹ãŠã®ã³ã³ãã¥ãŒã¿ã¢ãŒããã¯ãã£ã«ã¯ããã€ã³ã¿ã®æŽåãªã©ããããŸã ã ã€ãŸããããŒã¿åãžã®ãã€ã³ã¿ã¯2ã®ã¹ãä¹ã®åæ°ã§ãªããã°ãªããªããšããããšã§ãã ããšãã°ã4ãã€ãã®intãžã®ãã€ã³ã¿ãŒã¯4ã®åæ°ã§ãªããã°ãªããŸããã ãã€ã³ã¿ãŒã®äœçœ®åããã«ãã£ãŠèª²ããããå¶éã«éåãããšãããã©ãŒãã³ã¹ãå€§å¹ ã«äœäžããããã¢ããªã±ãŒã·ã§ã³ãå®å šã«äœäžãããããå¯èœæ§ããããŸãã ã¡ã¢ãªãžã®ã¢ãããã¯ãªèªã¿åããšæžã蟌ã¿ã«ãæ£ããã¢ã©ã€ã¡ã³ããå¿ èŠã§ãã èŠããã«ããã€ã³ã¿ãŒãæŽåãããããšã¯é倧ãªããšã§ããããããå£ãããšããã¹ãã§ã¯ãããŸããã
倿°ãäœæãããšãã³ã³ãã€ã©ã¯ã¢ã©ã€ã¡ã³ãããã§ãã¯ã§ããŸãã
void f(void) { int x; }
ãã ããåçã«å²ãåœãŠãããã¡ã¢ãªã§ã¯ç©äºã¯ããã»ã©åçŽã§ã¯ãããŸããã
int *ptr = malloc(sizeof(*ptr));
Mallocã¯ãããŒã¿ã®ã¿ã€ããäœã§ããããç¥ããŸããã4ãã€ããå²ãåœãŠãã ãã§ããããintã§ãããã2ã€ã®short aã4 char aããŸãã¯äœãä»ã®ãã®ã§ã¯ãããŸããã
ãããã£ãŠãé©åãªé 眮ãç¶æããããã«ã圌ã¯éåžžã«åå·çãªã¢ãããŒãã䜿çšãããã®å¢çãããããã¿ã€ãã®ããŒã¿ã«å®å šã«é©åããããã«é 眮ããããã€ã³ã¿ãŒãè¿ããŸãã Mac OS Xã§ã¯ã mallocã¯åžžã«16ãã€ãå¢çã«äœçœ®åããããããã€ã³ã¿ãŒãè¿ããŸãã
ã¢ã©ã€ã¡ã³ãã®ãããæªäœ¿çšã®ãããã¯ãã€ã³ã¿ãŒã«æ®ããŸãã 16ãã€ãã«ã¢ã©ã€ã¡ã³ãããã16é²ãã€ã³ã¿ãŒã¯æ¬¡ã®ããã«ãªããŸãã
0x-------0
16鲿°ã®æåŸã®æ¡ã¯åžžã«ãŒãã§ãã äžè¬ã«ããããã®æ¡ä»¶ã«é©åããªãå®å šã«æå¹ãªãã€ã³ã¿ãŒïŒããšãã°ãchar *ïŒãããå ŽåããããŸããããªããžã§ã¯ããžã®ãã€ã³ã¿ãŒã¯åžžã«ãŒããããã§çµäºããå¿ èŠããããŸãã
ã©ãã«ä»ããã€ã³ã¿ãŒã®å°ãã®çè«
ãã€ã³ã¿ãŒã®æåŸã«ãã空ã®ãããã«ã€ããŠç¥ã£ãŠããã°ãããã«é²ãã§ããããã®ã¢ããªã±ãŒã·ã§ã³ãèŠã€ããããšãã§ããŸãã ããããªããžã§ã¯ããžã®å®éã®ãã€ã³ã¿ã§ã¯ãªãããšãç€ºãææšãšããŠäœ¿çšããªãã®ã¯ãªãã§ããïŒ æ¬¡ã«ãé«äŸ¡ãªã¡ã¢ãªãå²ãåœãŠãããšãªããããã«ãã€ã³ã¿èªäœã«ããŒã¿ãä¿åã§ããŸããïŒ ã¯ããã¯ãããããã¯åãããŒã¯ããããã€ã³ã¿ãŒã§ãã
ã©ãã«ä»ããã€ã³ã¿ãŒã䜿çšããã·ã¹ãã ã¯ã远å ã®ãã§ãã¯ãå®è¡ããŸã-æäžäœãããã調ã¹ããŒãã®å Žåãå®éã®ãªããžã§ã¯ãããããŸãã ããããŠãããã§ããå Žåãããã¯ãªããžã§ã¯ãã§ã¯ãªããäœãä»ã®ãã®ã§ããããã€ã³ã¿ãŒããã®æ å ±ã¯éæšæºçãªæ¹æ³ã§æœåºããå¿ èŠããããŸãã éåžžãããŒã¿åã¯äžäœãããã®çŽåŸã«ä¿åããããã®åŸã«ããŒã¿èªäœãç¶ããŸãã
æå¹ãªãã€ããªãªããžã§ã¯ãã¯æ¬¡ã®ããã«ãªããŸãã
....0000 ^
ãããŠãããã¯ããŒã¯ããããã€ã³ã¿ãŒã§ãïŒ
....xxx1 ^
ãããã¯ãã¹ãŠããŸããŸãªæ¹æ³ã§å®è£ ã§ããŸãããObjective-Cã§ã¯ãã©ãã«ä»ããã€ã³ã¿ãŒã®æäžäœãããã¯åžžã«1ã§ãããæ¬¡ã®3ã€ã¯ãã€ã³ã¿ãŒã¯ã©ã¹ã瀺ããŸãã
ã©ãã«ä»ããã€ã³ã¿ãŒã®äœ¿çš
ã¿ã°ä»ããã€ã³ã¿ãŒã¯ããã¹ãŠããªããžã§ã¯ãã§ããèšèªã§ãã䜿çšãããŸãã 3ããªããžã§ã¯ãã§ããã3 + 4ã«2ã€ã®ãªããžã§ã¯ããå«ãŸããå Žåã®äžè²«æ§ãããã³3çªç®ã®ãªããžã§ã¯ããäœæããå Žåã§ãããªããžã§ã¯ãã«ã¡ã¢ãªãå²ãåœãŠãããããããŒã¿ãæœåºãããšãå šäœçãªããã©ãŒãã³ã¹ã§éèŠãªåœ¹å²ãæããå§ããŸãã ããã¯ãã¹ãŠããªããžã§ã¯ãã®äœæãé ãã¡ã¢ãªãžã®ã¢ã¯ã»ã¹ã誰ã䜿çšããªããªããžã§ã¯ããžã®å€ã®å ¥åã«æ©ãŸããã远å ã®ã³ã¹ããããæ°åé«ããªããŸãã
ã©ãã«ä»ããã€ã³ã¿ãŒã䜿çšãããšããããã®åã空ã®ãããã«åãŸããã¹ãŠã®ã¿ã€ãã®ãããã®éå¢ããè§£æŸãããŸãã å°ããªintã¯ããã®åœ¹å²ã®çæ³çãªåè£ã§ããã¹ããŒã¹ãã»ãšãã©å æãããããããå Žæã§äœ¿çšãããŸãã
ããã¯æ®éã®ããªãªãã©ã®ããã«èŠãããã§ãïŒ
0000 0000 0000 0000 0000 0000 0000 0011
ãããŠãããã«ããŒã¯ããããã€ã³ã¿ãŒã«é ããã3ã€ããããŸãã
0000 0000 0000 0000 0000 0000 0011 1011 ^ ^ ^ | | | (5) |
ããã§ã¯ã5ã䜿çšããŠintã瀺ãããšãææ¡ããŸããããå®éã«ã¯ãããã¯ã·ã¹ãã ã®è£éã«çãŸãããã¹ãŠããã€ã§ã倿Žã§ããŸãã
芳å¯è ã¯ããããã32ãããã·ã¹ãã ã«ã¯28ãããããæ®ã£ãŠãããã64ãããã·ã¹ãã ã«ã¯60ãããããæ®ã£ãŠããªãããšã«ãã§ã«æ°ä»ããŠããã§ãããã ãŸããæŽæ°ã¯å€§ããªå€ãåãããšãã§ããŸãã ããã§ãããã¹ãŠã®intãã©ãã«ä»ããã€ã³ã¿ãŒã§é衚瀺ã«ã§ããããã§ã¯ãããŸãããäžéšã®ãŠãŒã¶ãŒã¯æ¬æ Œçãªãªããžã§ã¯ããäœæããå¿ èŠããããŸãã
ãã¹ãŠã1ã€ã®ãã€ã³ã¿ã«åãŸãå Žåãåå¥ã®ã¡ã¢ãªãå²ãåœãŠãå¿ èŠã¯ãããŸãããã¯ãªã¢ããŸãã ãŸããå¥ã®ãªããžã§ã¯ãã«å²ãåœãŠãå¿ èŠã®ããã¡ã¢ãªãå°ãç¯çŽããã ãã§ãã 3ã€ãš4ã€ã远å ããå Žåãããã¯åãã«è¶³ããªãããã«æãããããããŸããããæ°å€ã«å¯Ÿããæäœã倿°ããå Žåããã®å¢å ã¯éåžžã«é¡èã§ãã
ãã€ã³ã¿ãŒå ã®ããŒã¿åã瀺ããããã®ååšã«ãããintã ãã§ãªããæµ®åå°æ°ç¹æ°ãããã«ã¯ããã€ãã®ASCIIæåïŒ64ãããã·ã¹ãã ã®å Žåã¯8ïŒãæ ŒçŽããããšãã§ããŸãã 1ã€ã®èŠçŽ ãžã®ãã€ã³ã¿ãŒãæã€é åã§ãããã©ãã«ä»ããã€ã³ã¿ãŒã«åãŸããŸãïŒ äžè¬ã«ãååã«å°ãããåºã䜿çšãããŠããããŒã¿åã¯ãã¿ã°ä»ããã€ã³ã¿ãŒå ã§äœ¿çšããããã®åªããåè£ã§ãã
ããŠãããªãçè«ãç·Žç¿ã«ç§»ããŸãããïŒ
NSNumberã®ã«ã¹ã¿ã å®è£ ã§ããMANumberãåºã«ããŠãã©ãã«ä»ããã€ã³ã¿ãŒã®ãµããŒãã远å ããŸãã
ã©ãã«ä»ããã€ã³ã¿ãŒã¯éåžžã«ãã©ã€ããŒããªAPIã§ãããå®éã®ãããžã§ã¯ãã§äœ¿çšããããšããèããããªãããšã«æ³šæããŠãã ããã ãªããžã§ã¯ãã®ã¯ã©ã¹ã決å®ããããã«å²ãåœãŠãããã®ã¯3ãããã ãã§ããåèšã§ãåæã«é¢äžã§ããã¯ã©ã¹ã¯8ã€ã ãã§ãã 誀ã£ãŠAppleã䜿çšããã¯ã©ã¹ãšäº€å·®ããå Žå-ããããã¹ãŠããã©ãã«ã§ãã ãŸãããã®æ å ±ã¯çµ¶å¯Ÿã«ãã€ã§ãå€åããå¯èœæ§ãããããããã€ã§ãçœå®³ãçºçããå¯èœæ§ã¯100ïŒ ã«çžåœããŸãã
ãã ããããããå®å šã«äœ¿çšããæ©äŒããªããŠããç§ãã¡ã圌ããšéã¶ããšã劚ãããã®ã¯äœããããŸããã
ãããå§ããŸãããã private _objc_insert_tagged_isa颿°ã䜿çšãããšãç¹å®ã®ã¯ã©ã¹ãç¹å®ã®ã¿ã°ã«åºå®ã§ããŸã ã 圌女ã®ãããã¿ã€ãã¯æ¬¡ã®ãšããã§ãã
void _objc_insert_tagged_isa(unsigned char slotNumber, Class isa);
ã¹ãããçªå·ïŒã¿ã°ïŒãšå¿ èŠãªã¯ã©ã¹ãããã«æž¡ããå®è¡æã«å°æ¥äœ¿çšããããã«ç¹å®ã®ããŒãã«ã«ããããé 眮ããŸãã
ã©ãã«ä»ããã€ã³ã¿ãŒã®ã»ãšãã©ãã¹ãŠã®ã¯ã©ã¹ã«ã¯ãå€ããã€ã³ã¿ãŒã«åãŸããªãå Žåã«éåžžã®ãªããžã§ã¯ããäœæãããã€ã³ã¯ã©ã¹ãå¿ èŠã§ãã NSNumberã®å Žåããããã¯ç¹ã«å€§ããªintãšdoubleã«ãªããŸããããã€ã³ã¿ãŒã«è©°ã蟌ãã®ã¯éåžžã«å°é£ã§ãããããã§ã¯è¡ããŸããã
ããã«ã¯2ã€ã®ã¢ãããŒãããããŸãã 1ã€ã¯ãäž¡æ¹ã®åå«ã§ç¹°ãè¿ãããã³ãŒãã®å ±éã®ç¥å ã䜿çšããŠã2ã€ã®å®å šã«ç°ãªãã¯ã©ã¹ãäœæããããšã§ãã 2ã€ç®ã¯ã1ã€ã®ã¯ã©ã¹ã®ãã¬ãŒã ã¯ãŒã¯ã§ãä¿åããå¿ èŠãããå€ã«å¿ããŠç°ãªãã³ãŒãã䜿çšããããšã§ãã 2çªç®ã®ã¢ãããŒãã䜿çšããã®ã§ããã®ç¹å®ã®ã±ãŒã¹ã§ã¯ç°¡åã«æããŸããã
倿°ã®å€ãä¿åããããã«ã unionã䜿çšããŸããïŒ
union Value { long long i; unsigned long long u; double d; };
以äžã¯ãã©ãã«ä»ããã€ã³ã¿ãŒã®æ å ±ãå®çŸ©ããããã€ãã®å®æ°ã§ãã æå-ã¹ãããçªå·ãç§ã¯ããã1ã«çããããŸããïŒ
const int kSlot = 1;
ãŸããã©ãã«ä»ããã€ã³ã¿ãŒã®æ°ã決å®ããããšã決å®ããŸãããããã¯ãå€ãããã«æœåºããããã«å¿ èŠã§ãã
const int kTagBits = 4;
å€èªäœã«å ããŠãMANumberã¯ãã®åãæ ŒçŽãããã®æäœæ¹æ³ã瀺ããŸãããã¹ãŠãæå€§ã«å§çž®ããå¿ èŠããããããå¯èœãªåã¯3ã€ãããªãããããã®ããã«2ããããéžæããŸããã
const int kTypeBits = 2;
ããã«ãµããŒãã¯å®è£ ããŸããã§ããããéåžžã®MANumberãšã®åäžæ§ãç¶æããå°æ¥ã®ããã«ãµããŒãã®å¯èœæ§ãé«ããããã«ããŸã ãã®å Žæãæ®ããŸããã
æåŸã«ãæ ŒçŽããæŽæ°ã®ã¿ã€ãã¯é·ãã®ã§ãå¿ èŠãªãããæ°ã確å®ã«ææ¡ããŠãããšäŸ¿å©ã§ãã
const int kLongLongBits = sizeof(long long) * CHAR_BIT;
ããã§ã¯ããã€ã³ã¿ãŒã®ã¿ã€ããé·ããšä»®å®ããŸãã32ãããã·ã¹ãã ããµããŒãããããšããŸããã§ããã
䟿å®äžããã«ããŒé¢æ°ãããã€ãäœæããŸããã æåã¯ãããŒã¿åãšå€ãå ¥åãšããŠãã©ãã«ä»ãMANumberãäœæããŸãã
static id TaggedPointer(unsigned long long value, unsigned type) {
ããŒã¯ããããã€ã³ã¿ãŒã®æ§é ãæãåºãããŠãã ããã æäžäœãããã¯åžžã«1ã§ãã ãã®åŸã«ãªããžã§ã¯ãã®ã¯ã©ã¹ã瀺ã3ããããç¶ãããªããžã§ã¯ãã®ããŒã¿ã®ã¿ãç¶ããŸãã ç§ãã¡ã®å Žåããããã¯ã¿ã€ããæ±ºå®ãã2ãããã§ããããã®åŸã«å€èªäœããããŸãã 以äžã¯ããããããšã®æäœã䜿çšããŠããã®ãã¹ãŠã®æ å ±ãçµã¿åãããŠèšé²ããè¡ã§ãã
id ptr = (__bridge id)(void *)((value << (kTagBits + kTypeBits)) | (type << kTagBits) | (kSlot << 1) | 1);
å¥åŠãªããã«ãã£ã¹ãã£ã³ã°ã«ã€ããŠã¯-ç§ã¯ARCã䜿çšããŠãã ã圌ã¯ãã®åé¡ã«é¢ããŠéåžžã«éžæçã§ãã ãããã£ãŠããªããžã§ã¯ããžã®ãã€ã³ã¿ãŒããªããžã§ã¯ããžã®ãã€ã³ã¿ãŒã«å€æããå Žåã¯ã__ bridgeãå¿ èŠã§ãããintã§ããã€ã³ã¿ãŒã倿ã§ããŸããã ãã®ãããæåã«void *ã«å€æããæ¬¡ã«ããããã¹ãŠããªããžã§ã¯ãã«å€æããŸãã
ããã ãã§ããä»ãæ°ããäœæãããã€ã³ã¿ãŒãè¿ããŸãã
return ptr; }
ãŸãããã€ã³ã¿ãŒãããŒã¯ãããŠãããã©ããããã§ãã¯ãã颿°ãäœæããŸããã 圌女ãè¡ãããšã¯ãäžäœãããããã§ãã¯ããããšã ãã§ãããæããªããã«ãã£ã¹ãã®ããã«ã圌女ã¯å¥ã®é¢æ°ã«å ¥ããªããã°ãªããŸããã§ããã
static BOOL IsTaggedPointer(id pointer) { uintptr_t value = (uintptr_t)(__bridge void *)pointer; return value & 1; }
ãããŠæåŸã«ãã©ãã«ä»ããã€ã³ã¿ãŒãããã¹ãŠã®æ å ±ãæœåºãã颿°ã Cã¯äžåºŠã«è€æ°ã®å€ãè¿ãããšããµããŒãããŠããªãããããã®ããã®ç¹å¥ãªæ§é ãäœæããŸãããåãšå€èªäœãå«ãŸããŠããŸã
struct TaggedPointerComponents { unsigned long long value; unsigned type; };
ãã®é¢æ°ã¯ãæåã«ãéåžžã«å倿ã䜿çšããŠãéæ¹åã«ã®ã¿ãã€ã³ã¿ãŒãintã«å€æããŸãã
static struct TaggedPointerComponents ReadTaggedPointer(id pointer) { uintptr_t value = (uintptr_t)(__bridge void *)pointer;
次ã«ãå¿ èŠãªæ å ±ã®æœåºãéå§ããŸãã æåã®4ãããã¯ç¡èŠã§ããå€ã¯åçŽãªã·ããã«ãã£ãŠæœåºãããŸãã
struct TaggedPointerComponents components = { value >> (kTagBits + kTypeBits),
ã¿ã€ããååŸããã«ã¯ãã·ããããã ãã§ãªãããã¹ã¯ãé©çšããå¿ èŠããããŸã
(value >> kTagBits) & ((1ULL << kTypeBits) - 1) };
ãã®çµæããã¹ãŠã®ã³ã³ããŒãã³ããåä¿¡ãããåçŽã«æ§é äœã®åœ¢ã§è¿ãããŸãã
return components; }
ããæç¹ã§ã _objc_insert_tagged_isa颿°ãåŒã³åºããŠãã©ãã«ä»ããã€ã³ã¿ãŒã§å®è¡ãããã¯ã©ã¹ã§ããããšãã©ã³ã¿ã€ã ã«éç¥ããå¿ èŠããããŸãã ããã«æé©ãªã®ã¯+åæåã§ãã ã»ãã¥ãªãã£äžã®çç±ãããObjective-Cã©ã³ã¿ã€ã ã¯ã¹ãããã®æžãæãã奜ãŸãªããããæåã«nilãæžã蟌ãå¿ èŠããããæ¬¡ã«æ°ããã¯ã©ã¹ã®ã¿ãèšè¿°ããå¿ èŠããããŸãã
+ (void)initialize { if(self == [MANumber class]) { _objc_insert_tagged_isa(kSlot, nil); _objc_insert_tagged_isa(kSlot, self); } }
ããã§ãã©ãã«ä»ããã€ã³ã¿ãŒãäœæããããã»ã¹ã«é²ãããšãã§ããŸãã + numberWithLongLongïŒãš+ numberWithUnsignedLongLongïŒã® 2ã€ã®ã¡ãœãããäœæããŸããã ãããã®ã¡ãœããã¯ãã©ãã«ä»ããã€ã³ã¿ãŒã«ãªããžã§ã¯ããäœæããããšããŸããå€ã倧ããããå Žåã¯ãéåžžã®ãªããžã§ã¯ããäœæããã ãã§ãã
ãããã®ã¡ãœããã¯ãç¹å®ã®å€ã»ããã«å¯ŸããŠã®ã¿ã©ãã«ä»ããã€ã³ã¿ãŒãäœæã§ããŸãããããã¯ãkLongLongBitsãkTagBitsãkTypeBitsããŸãã¯64ãããã·ã¹ãã ã®58ãããã«åãŸãå¿ èŠããããŸãã 笊å·ãåèšãæå€§long longå€ã¯57åã®2ãæå°å€ã¯-57ã瀺ãããã«1ããããå¿ èŠã§ãã
+ (id)numberWithLongLong: (long long)value { long long taggedMax = (1ULL << (kLongLongBits - kTagBits - kTypeBits - 1)) - 1; long long taggedMin = -taggedMax - 1;
æãã·ã³ãã«ãªãŸãŸã§ãã å€ãç¯å²å€ã®å Žåãalloc / initã䜿çšããŠéåžžã®ãã³ã¹ãå®è¡ããŸãã ãã以å€ã®å Žåã¯ãæå®ãããå€ãšã¯ã©ã¹INTã䜿çšããŠã©ãã«ä»ããã€ã³ã¿ãŒãäœæããŸãã
if(value > taggedMax || value < taggedMin) return [[self alloc] initWithLongLong: value]; else return TaggedPointer(value, INT); }
笊å·ãªãlong longã®å Žåãäžå¿ èŠãªç¬Šå·ãããã«ããå€ã»ããã®å¢å ãé€ããŠããã¹ãŠãåãã§ãã
+ (id)numberWithUnsignedLongLong:(unsigned long long)value { unsigned long long taggedMax = (1ULL << (kLongLongBits - kTagBits - kTypeBits)) - 1; if(value > taggedMax) return [[self alloc] initWithUnsignedLongLong: value]; else return (id)TaggedPointer(value, UINT); }
ããã§ããããããã¹ã¯ãªã©ãæ°ã«ããã«[self type]ãåŒã³åºãããšãã§ããããã«ããã€ã³ã¿ãŒçšã®åã¢ã¯ã»ãµãŒãå¿ èŠã§ãã 圌ãããããšã¯ãIsTaggedPointer颿°ã§ãã€ã³ã¿ãŒããã§ãã¯ããããšã ãã§ããã©ãã«ãä»ããŠããå Žåã¯ãReadTaggedPointerãåŒã³åºããŸãã ãã€ã³ã¿ãŒãæ£åžžãªå Žåã¯ã_typeãè¿ãã ãã§ãã
- (int)type { if(IsTaggedPointer(self)) return ReadTaggedPointer(self).type; else return _type; }
æå³ã®ã¢ã¯ã»ãµãŒã¯ãèšå·ã®é£ããã®ããã«ãããè€éã«ãªããŸãã ãŸãããããéåžžã®ãã€ã³ã¿ãŒãã©ããã確èªããŸãããã
- (union Value)value { if(!IsTaggedPointer(self)) { return _value; }
ã©ãã«ä»ãã®ãã®ã«ã€ããŠã¯ããŸãReadTaggedPointerã䜿çšããŠå€ãèªã¿åãå¿ èŠããããŸãã åºåã§ã¯ãunsigned long longããããããå€ã«å®éã«ç¬Šå·ãããå Žåã¯å°ãäœæ¥ããå¿ èŠããããŸãã
else { unsigned long long value = ReadTaggedPointer(self).value;
æ»ãå€ã®union Valueåã®ããŒã«ã«å€æ°ãäœæããŸãã
union Value v;
笊å·ãªãã®å Žåããã¹ãŠãåçŽã§ã-å€ãvã«å ¥ããã°ãããã ãã§ãïŒ
int type = [self type]; if(type == UINT) { vu = value; }
眲åä»ãã§ã¯ããã¹ãŠãããã»ã©åçŽã§ã¯ãããŸããã ãŸãã笊å·ãããã確èªããŸã-ãããçªå·57ã«é ãããŠããŸãïŒ
else if(type == INT) { unsigned long long signBit = (1ULL << (kLongLongBits - kTagBits - kTypeBits - 1));
ãããã1ã«çããå Žåã57ãããã«ç¶ããã¹ãŠã®ãããã«åäœãå ¥åããå¿ èŠããããŸããããã¯ãæå®ãããlong longãæå¹ãª64ãããã®è² æ°ã«ãªãããã«å¿ èŠã§ãã ãã®æé ã¯ç¬Šå·æ¡åŒµãšåŒã°ããèŠããã«ãã®æ¬è³ªã¯æ¬¡ã®ãšããã§ããè² ã®æ°ã¯1ã§å§ãŸããæåã®ãŒãã¯æåã®éèŠãªãããã§ãã ãããã£ãŠãè² ã®æ°ãå±éããã«ã¯ãåã«ãŠããããå·Šã«è¿œå ããŸãã
if(value & signBit) { unsigned long long mask = (((1ULL << kTagBits + kTypeBits) - 1) << (kLongLongBits - kTagBits - kTypeBits)); value |= mask; }
æ£ã®æ°ã§äœãããå¿ èŠã¯ãããŸãã-ãããã¯ãã§ã«å·ŠåŽããŒãã§æºããããŠããŸãã ãããã£ãŠãvãå ¥åããã ãã§ãã
vi = value; }
ä»ã®ã¿ã€ããååŸããå Žåãåé¡ãçºçãããããç Žæ£ããå¿ èŠããããŸãã
else abort();
ãã®çµæãvãè¿ããŸãã
return v; } }
ãã®ã³ãŒãããã¹ãŠäœæããããéåžžã©ããæ°ããMANumberãæäœããæ©äŒãåŸãããŸããå¯äžã®éãã¯ãå€ã«çŽæ¥ã¢ã¯ã»ã¹ããã®ã§ã¯ãªããã¢ã¯ã»ãµãŒã¡ãœãããä»ããŠã¢ã¯ã»ã¹ããå¿ èŠãããããšã§ãã ããã«ãã©ãã«ä»ãããã³éåžžã®MANumberãcompareïŒããã³isEqualïŒãšæ¯èŒ ã§ããŸãã
çµè«
ã©ãã«ä»ããã€ã³ã¿ãŒã¯ãCocoaããã³Objective-Cã©ã³ã¿ã€ã ãžã®åªããè¿œå æ©èœã§ãããNSNumberã䜿çšããéã®äœæ¥é床ãå€§å¹ ã«åäžãããã¡ã¢ãªã³ã¹ããåæžã§ããŸãã
NSNumberã®å éšããã€ã¹ã«å ãåœãŠãã©ãã«ä»ããã€ã³ã¿ãŒã§åäœããç¬èªã®ã¯ã©ã¹ãäœæã§ããŸããã空ãã¹ãããã®æ°ãéåžžã«éãããŠãããããå®éã®ã³ãŒãã§äœ¿çšããæ¹æ³ã¯ãããŸããã ããã¯çŽç²ã«Cocoaã®ç¹æš©ã§ããããã®äœæ¥ãå€§å¹ ã«å éããŸãã
ãŸããããã¯å®å šã«å®è¡ããããã®ãããªçŽ æŽãããã¡ã«ããºã ãåçŽãªNSNumberã®äžã«é ãããŠããããšãåã¶ããšãã§ããã ãã§ãã
ïŒãã€ã¯ã¢ãã·ã¥ããã®æ°ããéææ¥ã®QïŒAã®ç¡æç¿»èš³ïŒ