Что на самом деле делает NSLog? - PullRequest
3 голосов
/ 21 августа 2010

У меня странная проблема.Я использую метод из частных структур Apple в моем приложении.Когда я звоню в первый раз, это работает.Когда я вызываю его во второй раз сразу, без перерыва, происходит сбой.Тем не менее, если я поставлю NSLog между двумя вызовами, это прекрасно работает.Поэтому я пытаюсь удалить NSLog и поместить for-loop, sleep (), printf ("...") и fprintf (stderr, "...") между ними, чтобы эмулировать NSLog, но это не помогает.Мне интересно, откуда этот метод знает, что я использую NSLog?Другими словами, что на самом деле NSLog влияет на поведение метода?

Большое спасибо!

РЕДАКТИРОВАТЬ:

Мне кажетсяДля решения этой проблемы.Я поделюсь своим решением здесь и надеюсь, что оно может быть полезным для некоторых людей.

Я создаю приложение, связанное с несколькими касаниями, используя MultitouchSupport.framework.Я скопировал код из http://aladino.dmi.unict.it/?a=multitouch и добавил CFRelease в конце цикла.Итак, в основном мой основной метод выглядит следующим образом:

int main(void) { 
    int i; 
    NSMutableArray* deviceList = (NSMutableArray*)MTDeviceCreateList(); //grab our device list 
    for(i = 0; i<[deviceList count]; i++) { //iterate available devices 
        MTRegisterContactFrameCallback([deviceList objectAtIndex:i], touchCallback); //assign callback for device 
        MTDeviceStart([deviceList objectAtIndex:i], 0); //start sending events 
    }
    CFRelease((CFMutableArrayRef)deviceList); 
    printf("Ctrl-C to abort\n"); 
    sleep(-1); 
    return 0; 
}

Через некоторое время он покажет «Программа получила сигнал:« EXC_BAD_ACCESS »».А вот трассировка стека:

#0 0x7fff8795496e in ParsedMultitouchFrameRepInitialize
#1 0x7fff879565b1 in mt_HandleMultitouchFrame
#2 0x7fff87955a03 in mt_DequeueDataFromDriver
#3 0x7fff87955b29 in mt_DequeueMultitouchDataFromDriverThreadEntry
#4 0x7fff831b3456 in _pthread_start
#5 0x7fff831b3309 in thread_start

Однако, если я поставлю NSLog ниже MTDeviceStart, он не будет аварийно завершаться.

Причина, по которой я добавил CFRelease((CFMutableArrayRef)deviceList) в исходный код, заключается в том, что ядумаю, что объекты, созданные из функций с именем * Create * или * Copy *, должны быть освобождены сами.Но оказывается, что если я удаляю его, как это делает оригинальный код, он не рухнет, даже без использования NSLog.

Итак, может быть, это потому, что я слишком рано выпускаю deviceList?Но если это так, почему NSLog, кажется, может предотвратить сбой?

Ответы [ 4 ]

2 голосов
/ 21 августа 2010

Что-то похожее на это:

static inline void NSLogMessageString(NSString *string){
  NSString *date=[[NSDate date]
   descriptionWithCalendarFormat:@"%Y-%m-%d %H:%M:%S.%F"
                        timeZone:nil locale:nil];
  NSString *process=[[NSProcessInfo processInfo] processName];

  NSLogFormat(@"%@ %@[%d:%lx] %@",date,process,NSPlatformProcessID(),NSPlatformThreadID(),string);
}

void NSLogv(NSString *format,va_list arguments) {
  NSString *string=NSStringNewWithFormat(format,nil,arguments,NULL);

  NSLogMessageString(string);

 [string release];
}

void NSLog(NSString *format,...) {
  va_list arguments;

  va_start(arguments,format);

  NSLogv(format,arguments);
}

Спасибо, что задали этот вопрос, lol, я хотел переписать его, чтобы добавить переменные отладки, то есть при необходимости можно отключить все вызовы NSLogging ..

1 голос
/ 28 июля 2012

NSLog может влиять на проблемы, подобные той, с которой вы сталкиваетесь, потому что он влияет на порядок выполнения потоков, потому что когда вы вызываете NSLog в фоновом потоке, он должен получить эксклюзивный доступ к stdout.Отладка printf Сложные проблемы с потоками часто приводят к «heisenbugs» по этой причине (т.е. они меняют поведение, когда вы пытаетесь их исследовать).

1 голос
/ 21 августа 2010

Это занимает много времени.Я не уверен почему.Он печатает дату / время, имя процесса, идентификатор процесса, идентификатор потока и (наконец) строку, которую вы запросили.Я думаю также отправляет сообщение журнала в syslogd (консоль Xcode или iPCU отображает многострочные NSLogs как одну запись; я забыл, какая);IPC там может быть значительным.

Попробуйте использовать syslog () (#import <syslog.h>, а затем syslog(LOG_INFO, "Hello there!");, если он работает, но у вас нет вывода, попробуйте изменить приоритет (см. man 3 syslog).

0 голосов
/ 21 августа 2010

Это может быть проблема с управлением памятью: возможно, посторонний выпуск. Если вы опубликуете трассировку, это может помочь вам отследить проблему. (Оказывается, кто-то в Твиттере, за которым я следил, упоминал что-то вроде этого прошлой ночью).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...