2010-03-18 4 views
0

Я нашел то, что, по моему мнению, может быть ошибкой с Ivar и Objective-C. Я использую XCode 3.2.1 и связанные библиотеки, разрабатывая 64-битное приложение на X86_64 (MacBook Pro).Определения Ivar показывают кодировку «длинного» типа как кодировку «длинного длинного»

Где бы я ожидал, что кодировка типа для «longVal» будет «l», кодировка Ivar показывает «q» (которая является «длинной длинной»).

Кто-нибудь еще видел это? Упрощенный код и вывод следующим образом:

Код:

#import <Foundation/Foundation.h> 
#import <objc/runtime.h> 
@interface Bug : NSObject 
{ 
    long  longVal; 
    long long longerVal; 
} 
@property (nonatomic,assign) long longVal; 
@property (nonatomic,assign) long long longerVal; 
@end 

@implementation Bug 

@synthesize longVal,longerVal; 

@end 


int main (int argc, const char * argv[]) { 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 
    unsigned int ivarCount=0; 
    Ivar *ivars= class_copyIvarList([Bug class], &ivarCount); 

    for(unsigned int x=0;x<ivarCount;x++) { 
     NSLog(@"Name [%@] encoding [%@]", 
     [NSString stringWithCString:ivar_getName(ivars[x]) encoding:NSUTF8StringEncoding], 
       [NSString stringWithCString:ivar_getTypeEncoding(ivars[x]) encoding:NSUTF8StringEncoding]); 
    } 

    [pool drain]; 
    return 0; 
} 

А вот выход из отладочной консоли:

This GDB was configured as "x86_64-apple-darwin".tty /dev/ttys000 
Loading program into debugger… 
sharedlibrary apply-load-rules all 
Program loaded. 
run 
[Switching to process 6048] 
Running… 
2010-03-17 22:16:29.138 ivarbug[6048:a0f] Name [longVal] encoding [q] 
2010-03-17 22:16:29.146 ivarbug[6048:a0f] Name [longerVal] encoding [q] 
(gdb) continue 

Не красивая картинка!

- Frank

+0

Что сказал zneak; нет ошибки. Тем не менее, есть много других ошибок с '@ encode' и друзьями. Вниз по этому пути лежат ловушки. Пожалуйста, убедитесь, что вы делаете ошибки в отношении как конкретных проблем, так и ошибки, детализируя то, что вы пытаетесь сделать. – bbum

ответ

2

Это не ошибка. Компилятор GCC под архитектурой 64 битов выбирает для представления long s как 64-битные целые числа. Вы можете проверить сами:

printf("%lu\n", sizeof(long)); // will give "8" 

Напомним, что стандарт C определяет минимальные размеры для целочисленных типов. long гарантированно не менее 32 бит.

+0

zneak, Paul and bbum: Выполнение функции [bug performSelector: @selector (setLongVal :) withObject: [NSNumber numberWithLong: (long) 87]]; Результаты: 2010-03-18 06: 55: 48.163 ivarbug [1006: a0f] Ошибка выхода после выполненияSelector [longVal [4296082976]] –

+0

Однако использование NSInvocation, похоже, работает для типа. Он использовал «performSelector», который поднял мои брови, и для начала я начал рыть. –

+0

@Frank C .: Это тоже не ошибка. Ваша собственность ожидает значение 'long', и вы даете им значение NSNumber *. Вы не можете использовать 'performSelector: withObject:' для методов, типы аргументов которых не являются 'id'; это совпадение «сработало», потому что «long» и указатели имеют одинаковый размер под моделью LP64. Теперь у вас есть, скорее всего, адрес памяти вашего объекта NSNumber. См. Документ для 'performSelector: withObject:'. – zneak

0

Mac OS X, Linux и большинство других 64-разрядных операционных систем используют модель LP64, где longs и указатели 64 бит, а int 32 бит.