3

私は奇妙な問題を抱えています。私は自分のアプリケーションでAppleのプライベートフレームワークのメソッドを使用しています。初めて呼び出すと動作します。何もせずにすぐに2回目に呼び出すと、クラッシュします。ただし、2つの呼び出しの間にNSLogを配置すると、うまく機能します。そこで、NSLogを削除し、forループ、sleep()、printf( "...")、およびfprintf(stderr、 "...")をそれらの間に配置して、NSLogをエミュレートしようとしましたが、役に立ちません。NSLogを使用していることをメソッドがどのように認識しているのでしょうか。言い換えると、NSLogはメソッドの動作に影響を与えるために実際に何をしますか?

どうもありがとうございます!

編集:

私はこの問題を解決しているようです。私はここで私の解決策を共有し、それが何人かの人々に役立つかもしれないことを願っています。

MultitouchSupport.frameworkを使用してマルチタッチ関連のアプリケーションを作成しています。http://aladino.dmi.unict.it/?a=multitouchからコードをコピーしCFRelease、ループの最後にaを追加しました。したがって、基本的に、私のメインメソッドは次のようになります。

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

4 に答える 4

2

これに似たもの:

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);
}

この質問をしてくれてありがとう笑、デバッグ変数を追加できるように書き直したかったので、必要に応じてすべての NSLogging 呼び出しをオフにできました..

于 2010-08-21T08:00:19.887 に答える
1

時間がかかる。理由はわかりません。日付/時刻、プロセス名、プロセス ID、スレッド ID、および (最終的に) 要求した文字列が表示されます。ログメッセージもsyslogdに送信すると思います(XcodeまたはiPCUのコンソールのいずれかが複数行のNSLogを単一のエントリとして表示します。どちらかを忘れました)。そこのIPCは重要かもしれません。

syslog() を使用してみてください (#import <syslog.h>そしてsyslog(LOG_INFO, "Hello there!");、機能しても出力が得られない場合は、優先順位を変更してみてください ( を参照man 3 syslog)。

于 2010-08-21T05:08:02.730 に答える
1

NSLog は、バックグラウンド スレッドで NSLog を呼び出すときに stdout への排他的アクセスを取得する必要があるため、スレッドの実行順序に影響を与えるため、実行中のような問題に影響を与える可能性があります。スレッドに関するトリッキーな問題を printf でデバッグすると、この理由で "heisenbugs" が発生することがよくあります (つまり、調べようとすると動作が変わる)。

于 2012-07-27T20:30:09.417 に答える
0

メモリ管理の問題である可能性があります。おそらく無関係なリリースです。トレースバックを投稿すると、問題の追跡に役立つ場合があります。(結局のところ、私がフォローしている Twitter の誰かが昨夜、このようなことを言及しました)。

于 2010-08-21T04:55:19.577 に答える