বর্তমান থ্রেডটি মূল থ্রেড কিনা তা পরীক্ষা করে দেখুন


121

বর্তমান থ্রেডটি উদ্দেশ্য-সি এর মূল থ্রেড কিনা তা যাচাই করার কোনও উপায় আছে কি?

আমি এরকম কিছু করতে চাই।

  - (void)someMethod
  {
    if (IS_THIS_MAIN_THREAD?) {
      NSLog(@"ok. this is main thread.");
    } else {
      NSLog(@"don't call this method from other thread!");
    }
  }

অন্যান্য থ্রেড থেকে একটি পদ্ধতি কল সম্পর্কে ভুল কি?
ডেভিড 天宇 ওয়াং

উত্তর:



24

যদি আপনি চান যে কোনও পদ্ধতিটি মূল থ্রেডে কার্যকর করা যায় তবে আপনি এটি করতে পারেন:

- (void)someMethod
{
    dispatch_block_t block = ^{
        // Code for the method goes here
    };

    if ([NSThread isMainThread])
    {
        block();
    }
    else
    {
        dispatch_async(dispatch_get_main_queue(), block);
    }
}

5
পুরানো প্রশ্নের উত্তরগুলি নতুন উত্তর কীভাবে বিদ্যমান উত্তরের চেয়ে আলাদা তার ব্যাখ্যা থেকে উপকৃত হতে পারে।
জেসন অ্যালার

1
এটি ওভারকিল, যদি কিছু কাজ অবশ্যই মূল থ্রেডে করা উচিত হয় তবে আপনি মূল থ্রেডে আছেন কি না তা খতিয়ে দেখার কোনও সুবিধা নেই। কেবল করুনNSOperationQueue.mainQueue().addOperationWithBlock { //your work here }
এরিক

3
@ এরিক আমি সম্মত, তবে আপনি যদি ইতিমধ্যে মূল থ্রেডে অবিলম্বে এই পদ্ধতিটি কার্যকর করতে চান তবে কী হবে? আপনার পরামর্শে পদ্ধতিটি সর্বদা মূল অপারেশন সারি দ্বারা পরবর্তী সময়ে কার্যকর করার জন্য প্রেরণ করা হয়।
বোহেরনা

@ বোহরনা সঠিক, এটি সন্ধান করার মতো কিছু।
এরিক

@ বোহেরনা লেট মন্তব্য, তবে আপনি আপনার মন্তব্যে যে বক্তব্যটি করেছেন তা যদি আপনি আপনার উদাহরণের dispatch_sync()পরিবর্তে ব্যবহার করেন তবে তা আরও শক্তিশালী হবে dispatch_async()
কালেব


13

আপনি যদি মূল থ্রেডে আছেন কিনা তা যদি আপনি জানতে চান তবে আপনি কেবল ডিবাগারটি ব্যবহার করতে পারেন। আপনার আগ্রহী লাইনে একটি ব্রেকপয়েন্ট পয়েন্ট সেট করুন এবং আপনার প্রোগ্রামটি যখন এটি পৌঁছবে তখন এটিকে কল করুন:

(lldb) thread info

এটি আপনি যে থ্রেডে আছেন সে সম্পর্কে তথ্য প্রদর্শন করবে:

(lldb) thread info thread #1: tid = 0xe8ad0, 0x00000001083515a0 MyApp`MyApp.ViewController.sliderMoved (sender=0x00007fd221486340, self=0x00007fd22161c1a0)(ObjectiveC.UISlider) -> () + 112 at ViewController.swift:20, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1

যদি মানটি queueহয় com.apple.main-threadতবে আপনি মূল থ্রেডে রয়েছেন ।


6

নিম্নলিখিত প্যাটার্নটি নিশ্চিত করবে যে কোনও পদ্ধতিটি মূল থ্রেডে চালিত হয়েছে:

- (void)yourMethod {
    // make sure this runs on the main thread 
    if (![NSThread isMainThread]) {
        [self performSelectorOnMainThread:_cmd/*@selector(yourMethod)*/
                               withObject:nil
                            waitUntilDone:YES];
        return;
    }
    // put your code for yourMethod here
}

_cmdআপনার স্নিপেটটি যে পদ্ধতিতে ni • ᴥ • Al তে আটকানো হয়েছে তা স্বয়ংক্রিয়ভাবে ব্যবহার করবে
অ্যালবার্ট রেনশওয়া

3

দুইটি রাস্তা. @ রানোর উত্তর থেকে,

[[NSThread currentThread] isMainThread] ? NSLog(@"MAIN THREAD") : NSLog(@"NOT MAIN THREAD");

এছাড়াও,

[[NSThread mainThread] isEqual:[NSThread currentThread]] ? NSLog(@"MAIN THREAD") : NSLog(@"NOT MAIN THREAD");

3
void ensureOnMainQueue(void (^block)(void)) {

    if ([[NSOperationQueue currentQueue] isEqual:[NSOperationQueue mainQueue]]) {

        block();

    } else {

        [[NSOperationQueue mainQueue] addOperationWithBlock:^{

            block();

        }];

    }

}

নোট করুন যে আমি অপারেশন সারিটি পরীক্ষা করেছি, থ্রেডটি নয়, কারণ এটি আরও নিরাপদ পদ্ধতি


এটি গ্রহণযোগ্য উত্তর হওয়া উচিত, মূল থ্রেড! = মূল সারি
রেলপ্রেডে

2

মনোোটচ / জ্যামারিন আইওএসের জন্য আপনি চেকটি এইভাবে সম্পাদন করতে পারেন:

if (NSThread.Current.IsMainThread)
{
    DoSomething();
}
else
{
    BeginInvokeOnMainThread(() => DoSomething());
}


1

আসুন ওনমাইন কিউইউ = (প্রেরণ_কিউ_জেট_লাবেল (প্রেরণ_সামগ্রী_মাইন_কিউ ()) == প্রেরণ_কুই_জিট_এবেল (ডিআইএসপিএটিচ_সিইউআরইউ_কিউইউ_লবেল))

এই উত্তরটি https://stackoverflow.com/a/34685535/1530581 থেকে দেখুন


0

বিস্তারিত

  • সুইফ্ট 5.1, এক্সকোড 11.3.1

সমাধান 1. যে কোনও সারি সনাক্ত করুন

বর্তমান ডিসপ্যাচকিউ পান?

সমাধান 2. কেবলমাত্র মূল সারিটি সনাক্ত করুন

import Foundation

extension DispatchQueue {

    private struct QueueReference { weak var queue: DispatchQueue? }

    private static let key: DispatchSpecificKey<QueueReference> = {
        let key = DispatchSpecificKey<QueueReference>()
        let queue = DispatchQueue.main
        queue.setSpecific(key: key, value: QueueReference(queue: queue))
        return key
    }()

    static var isRunningOnMainQueue: Bool { getSpecific(key: key)?.queue == .main }
}

ব্যবহার

if DispatchQueue.isRunningOnMainQueue { ... }

নমুনা

func test(queue: DispatchQueue) {
    queue.async {
        print("--------------------------------------------------------")
        print("queue label: \(queue.label)")
        print("is running on main queue: \(DispatchQueue.isRunningOnMainQueue)")
    }
}

test(queue: DispatchQueue.main)
sleep(1)
test(queue: DispatchQueue.global(qos: .background))
sleep(1)
test(queue: DispatchQueue.global(qos: .unspecified))

ফলাফল (লগ)

--------------------------------------------------------
queue label: com.apple.root.background-qos
is running on main queue: false
--------------------------------------------------------
queue label: com.apple.root.default-qos
is running on main queue: false
--------------------------------------------------------
queue label: com.apple.main-thread
is running on main queue: true

0
Here is a way to detect what the current queue is
extension DispatchQueue {
    //Label of the current dispatch queue.
    static var currentQueueLabel: String { String(cString: __dispatch_queue_get_label(nil)) }

    /// Whether the current queue is a `NSBackgroundActivityScheduler` task.
    static var isCurrentQueueNSBackgroundActivitySchedulerQueue: Bool { currentQueueLabel.hasPrefix("com.apple.xpc.activity.") }

    /// Whether the current queue is a `Main` task.
    static var isCurrentQueueMainQueue: Bool { currentQueueLabel.hasPrefix("com.apple.main-thread") }
}

-2

হালনাগাদ: মনে হচ্ছে এটি সঠিক সমাধান নয়, কুইউ শিরোনাম অনুসারে @ ডেমোস্টেন উল্লিখিত হয়েছে

প্রথম চিন্তাটি আমার কাছে নিয়ে আসা হয়েছিল, যখন আমার এই কার্যকারিতাটির প্রয়োজন ছিল লাইনটি:

dispatch_get_main_queue() == dispatch_get_current_queue();

এবং গ্রহণযোগ্য সমাধানের দিকে চেয়েছিলেন:

[NSThread isMainThread];

খনি সমাধান 2.5 গুণ দ্রুত।

পিএস এবং হ্যাঁ, আমি যাচাই করেছি, এটি সমস্ত থ্রেডের জন্য কাজ করে


3
জ্ঞান তৈরি করে - আপনার পদ্ধতিটি আপত্তি-সি রানটাইম মেসেজিং সিস্টেমের ওভারহেডটিকে বাইপাস করে। যদিও আপনি এই কৌশলটি ব্যবহার করছেন, আমি বলব এটির একটি খারাপ কোড গন্ধ আছে, সম্ভবত এটি অকাল অপটিমাইজেশনের।
আর্টঅফ ওয়ারফেয়ার


33
আপনি এটি অ্যাপলের ক্যু.এই শিরোনামের বিবরণে পড়তে পারেন যেখানে dispatch_get_current_queue () সংজ্ঞায়িত করা হয়েছে: When dispatch_get_current_queue() is called on the main thread, it may or may not return the same value as dispatch_get_main_queue(). Comparing the two is not a valid way to test whether code is executing on the main thread.
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.