2011-01-24 1 views
0

Я играл с Objective-C выполнения и получения SIGSEGV при попытке распечатать описание объекта:Objective-C во время выполнения SIGSEGV на Descrption

#include <objc/runtime.h> 
#include <stdio.h> 
#include <stdlib.h> 


int 
main() 
{ 
    // SEL sAlloc = sel_registerName("alloc"); 
    SEL sInit = sel_registerName("init"); 
    SEL sDesc = sel_registerName("description"); 
    id desc; 
    Class nAuto = (Class)objc_getClass("NSAutoreleasePool"); 
    Class nObject = (Class)objc_getClass("NSObject"); 

    // Avoid __NSAutoreleaseNoPool warrning 
    id nsAuto = class_createInstance(nAuto, 0); 
    objc_msgSend(nsAuto, sInit); 

    id ns = class_createInstance(nObject, 0); 
    objc_msgSend(ns, sInit); 

    desc = objc_msgSend(ns, sDesc); 
    printf("%s\n", class_getName(ns->isa)); 
    printf("%s\n", class_getName(desc->isa)); // SIGSEGV triggered 
    NSLog(desc); 


    return EXIT_SUCCESS; 
} 

Так что, если кто-нибудь есть идея, почему это происходит , Благодаря

+0

как-то, глядя на код сборки около 'objc_msgSend' есть объяснение. Сразу после вызова есть инструкция cltq, знак которой расширяет регистр eax до rax. Поэтому мне просто интересно, почему 'objc_msgSend' объявляет о возврате 32-битного указателя? – mathk

+0

Кстати «NSLog (desc)» - это плохая практика; используйте 'NSLog (@"% @ ", desc)'. Что произойдет, если 'desc' содержит пробел'% @'? Это приведет к сбою вашей программы. Хотя, похоже, это не проблема, с которой вы сталкиваетесь. – Yuji

+0

Я основал. вызвано тем, что objc_msgSend необходимо выполнить перед использованием. Он написан в заголовке objc/message.h – mathk

ответ

0

objc_msgSend должны быть отлиты перед использованием:

desc = (IMP)objc_msgSend(ns, sDesc); 
Смежные вопросы