3

someMethoda)ユーザーがビューをタップしたとき、およびb)ユーザーがビューをドラッグしたときに呼び出されるメソッドがあります。には、ビューの上部にあるツールバーを非表示にし、それに応じてフレームをリセットsomeMethodするブロックがあります。UIView animateWithDurationユーザーがビューをドラッグするよりもタップするとsomeMethod、アニメーションがまだ完了している間に起動されますが、これは私が望む動作ではありません (単純にアニメーションをキャンセルしても、完了ブロックがまだ起動するため機能しません (確認しても'finished' BOOL) すべてのことを考慮して、アニメーションがまだ進行中のときにこのメソッドを起動したくないだけです。

明らかに、これに対する簡単な解決策は、 で手動ロックを設定しBOOL、ロックが解放された後にのみメソッドを呼び出すことを許可することです。

これを達成するためのよりエレガントな方法はありますか?これを達成するためにGCDまたは他のライブラリを使用することは可能ですか?

更新:同期を使用しようとしましたが、問題はメソッドがアニメーションを起動して終了することですが、アニメーションはまだ別のスレッドで実行されています。他のアイデアはありますか?

4

4 に答える 4

1

A timer running out does not imply or require a secondary thread. You're in control of what thread a timer is scheduled on. If you just schedule the timer on the main thread, then both things happen on the main thread.

The suggestions of using @synchronized achieve the effect that a given block of code is not running for the same object (whatever is the parameter of @synchronized) at the same time, but that's not the same thing as saying it's not run on two different threads.

If you want to detect if a method is called on a thread other than the main thread and then shunt it over to the main thread, you can use +[NSThread isMainThread] and dispatch_async(dispatch_get_main_queue(), ^{ /* re-call current method */ });.

于 2012-06-09T08:43:36.483 に答える
1

最新の iOS および OS X では、実行を制御するための最も洗練されたメカニズムは、ディスパッチ キューとブロックを使用することです。グローバル ロックの場合、単一のシリアル キューを使用して、重要なコードの実行中にそのスレッドの残りの実行を停止するかどうかに応じて、同期的または非同期的に要求を行うことができます。

どこかでキューをグローバルに宣言します。

dispatch_queue_t myQueue;

したがって、起動時にキューを作成します。

myQueue = dispatch_queue_create( "CRITICAL_SECTION", DISPATCH_QUEUE_SERIAL);    // FIFO

また、コードのクリティカル セクションを実行する場合は、次を使用します。

dispatch_sync( shpLockQueue, ^{
     // critical section here
});

必要に応じて、これらのブロックのいずれかでメソッドを呼び出したり、保護しているオブジェクト内にブロックを配置したりすることができます。

ルーチンがメイン スレッドで確実に実行されるようにする必要がある場合は、メイン ディスパッチ キューを使用できますが、それが不要な場合は、独自のキューを使用する方が効率的です。メイン キューを使用することを選択した場合、独自のキューを設定したり保存したりする必要はありません。コードを次の場所で実行するだけです。

dispatch_sync( dispatch_get_main_queue(), ^{
     // critical section here
});
于 2012-06-09T10:32:54.510 に答える
0

@synchronized() ブロックをお勧めします。これについての素晴らしいブログ投稿があります。

http://googlemac.blogspot.com/2006/10/synchronized-swimming.html

@synchronized(self) {
     [self someMethod];  
}
于 2012-06-09T08:39:03.507 に答える
0

Well even using just a global variable, doesn't guarantee mutual exclusion, since the variable is copied to the register before being updated, if that indeed is what you meant by "manual lock BOOL ..." and unfortunately their aren't any really elegant solutions .... Check out https://developer.apple.com/library/mac/ipad/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html

Good luck.

于 2012-06-09T08:42:00.163 に答える