にCFArrayRefをキャストするとき、これは素晴らしいです:クラッシュNSArrayの
これはEXC_BAD_ACCESSが発生します。NSArray
上documentationから
CFArrayRef windowIDList = CGWindowListCreate(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
NSLog(@"Array %@", (__bridge NSArray*) windowIDList);
にCFArrayRefをキャストするとき、これは素晴らしいです:クラッシュNSArrayの
これはEXC_BAD_ACCESSが発生します。NSArray
上documentationから
CFArrayRef windowIDList = CGWindowListCreate(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
NSLog(@"Array %@", (__bridge NSArray*) windowIDList);
NSArray
として作成された配列には、Objective-Cオブジェクトのように動作する要素しか含めることができません。
CFArray
として作成された配列には、適切なCFArrayCallBacks
をCFArrayCreate
に渡すと何も含めることができます。
CGWindowListCreate
はCFArray
を作成し、オブジェクトのように動作しませんが、CGWindowListCreate
はそれを気にしないCFArrayCallbacks
を使用しているもので、それを埋めています。
あなたは%@
書式指定子で、このCFArray
を印刷しようとすると、NSLog
アレイにObjective-Cの-description
メッセージを送信します。 CFArray
はObjective-C description
メッセージを各要素に送信することでこれを処理します。残念ながら、その要素はオブジェクトではないため、Objective-Cメッセージを送信することは不可能です。したがって、クラッシュ。
代わりにこれを試してください。
CFStringRef description = CFCopyDescription(windowIDList);
NSLog(@"Array %@", description);
CFRelease(description);
CFCopyDescription
関数ではなくそれぞれにObjective-Cのメッセージを送信しようとする、配列の各要素にCFArrayCallbacks
機能の1つを使用します。コールバックは配列要素をどのように扱うかを知っているので、うまく動作します。私は私のテストプログラムでは、この出力を得る:
2011-11-10 18:50:23.888 test[15156:707] <CFArray 0x1001140c0 [0x7fff7fd24ea0]>{type = mutable-small, count = 19, values = (
0 : <0x7d7>
1 : <0x2d>
2 : <0x20>
3 : <0x21>
4 : <0x1e>
5 : <0x9>
6 : <0x7a8>
7 : <0x2c>
8 : <0x2e>
9 : <0x743>
10 : <0x32>
11 : <0x85>
12 : <0x695>
13 : <0x62a>
14 : <0x62b>
15 : <0xa>
16 : <0x26>
17 : <0x18>
18 : <0x2>
)}
:
にNSArrayは、「フリーダイヤル架設されています"をCore Foundationの対応部 CFArrayリファレンスとともに使用しています。これが意味するのは、ブリッジタイプ のファンクションまたはメソッド呼び出しでCore Foundationタイプが であり、一方のタイプを他方のタイプにキャストするということです。 したがって、NSArray *パラメータを参照するAPIでは、 をCFArrayRefに渡し、APIでCFArrayRef パラメータを参照すると、NSArrayインスタンスを渡すことができます。この配列も NSArrayの具体的なサブクラスに適用されます。
したがって、問題は2つのメソッドを呼び出すことである必要があります。
現在のユーザーセッションのウィンドウの1についての情報 が含まれ、それぞれがCFDictionaryRefタイプの配列:ここでも、ドキュメント、
CGWindowListCopyWindowInfo
から値を返す持っています。目的の基準に一致する のウィンドウがない場合、この関数は空の 配列を返します。この関数をGUIセキュリティ セッションの外から呼び出した場合、またはウィンドウサーバーが実行されていない場合は、 NULLを返します。 CGWindowID値の配列が所望のウィンドウに対応:
と
CGWindowListCreate
戻り値を有しています。 目的の基準に一致するウィンドウがない場合、関数 は空の配列を返します。 GUIセキュリティセッションの外からこの関数を呼び出した場合、またはウィンドウサーバーが実行されていない場合、この 関数はNULLを返します。
NSLog(@"%@",array);
に電話すると、description
というメッセージが配列の各オブジェクトに送信されます。フロート、BOOLおよびintはこのメッセージに応答しません。たとえば、
NSLog(@"Printing 2: %@",2);
のエラーを取得しますが、エラーは、int
コールを使用する場合消える:CGWindowListCreate
はCGWindowID
値の配列を返して、あなたのケースのために
NSLog(@"Printing 2: %d",2);
を、これらの32ビットの符号なし整数です。したがって、彼らは%@
に応答しませんが、%u
に応答します。したがって、修正は%u
を使用して手動で配列を印刷することです。
OK、私は 'のNSLog( "アレイ%ldの" @ [(__bridgeにNSArray *)カウントwindowIDList])試してみました;'と、それは14と 'CFArrayGetCount(windowIDListを返します。 ) 'を返し、14も返すが、NSLog(@" Array%@ "、[(__bridge NSArray *)windowIDList objectAtIndex:1]);はまだクラッシュします。 –
それでは、 'CGWindowID'が' description'に応答しないという問題があります。これは、32ビットのunsigned intと思われる。 'NSLog(@" Array%u "、[(__bridge NSArray *)windowIDList objectAtIndex:0]); ' – PengOne
これは動作しますが、私はそれを取得しません。 –
ああ!さて、なぜそれがC配列のように半分、オブジェクトの半分のように振る舞っていたのかが分かります。答えをありがとう。 –