যখন একটি UIScrollView
(বা এর উত্পন্ন শ্রেণি) স্ক্রল করছে, মনে হচ্ছে NSTimers
স্ক্রোলটি শেষ না হওয়া পর্যন্ত যা চলছে সমস্তগুলি বিরতি হয়ে যায়।
এই কাছাকাছি পেতে একটি উপায় আছে? থ্রেডস? একটি অগ্রাধিকার সেটিং? কিছু?
যখন একটি UIScrollView
(বা এর উত্পন্ন শ্রেণি) স্ক্রল করছে, মনে হচ্ছে NSTimers
স্ক্রোলটি শেষ না হওয়া পর্যন্ত যা চলছে সমস্তগুলি বিরতি হয়ে যায়।
এই কাছাকাছি পেতে একটি উপায় আছে? থ্রেডস? একটি অগ্রাধিকার সেটিং? কিছু?
উত্তর:
সমাধান কার্যকর করার সহজ ও সহজ কাজটি হ'ল:
NSTimer *timer = [NSTimer timerWithTimeInterval:...
target:...
selector:....
userInfo:...
repeats:...];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
যে কেউ সুইফট 3 ব্যবহার করেন
timer = Timer.scheduledTimer(timeInterval: 0.1,
target: self,
selector: aSelector,
userInfo: nil,
repeats: true)
RunLoop.main.add(timer, forMode: RunLoopMode.commonModes)
timer = Timer(timeInterval: 0.1, target: self, selector: aSelector, userInfo: nil, repeats: true)
পরিবর্তে প্রথম কমান্ড হিসাবে কল করা ভাল Timer.scheduleTimer()
, কারণ scheduleTimer()
রানলুপে টাইমার যুক্ত করে এবং পরবর্তী কলটি একই রানলুপে যোগ করা হলেও ভিন্ন মোডের সাথে যুক্ত হয়। দু'বার একই কাজ করবেন না।
এটি সুইফ্ট সংস্করণ।
timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: aSelector, userInfo: nil, repeats: true)
NSRunLoop.mainRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes)
আপনি যদি স্ক্রল করার সময় টাইমারগুলিকে গুলি চালাতে চান তবে আপনাকে অন্য থ্রেড এবং অন্য একটি রান লুপ চালাতে হবে; যেহেতু ইভেন্ট লুপের অংশ হিসাবে টাইমারগুলি প্রক্রিয়াজাত করা হয়, আপনি যদি নিজের ভিউ স্ক্রোল করার প্রক্রিয়াতে ব্যস্ত হন, আপনি কখনই টাইমারগুলির কাছাকাছি আসবেন না। যদিও অন্য থ্রেডগুলিতে টাইমার চালনার পারফ / ব্যাটারি পেনাল্টি এই কেসটি পরিচালনা করার পক্ষে উপযুক্ত নয়।
যে কেউ সুইফট 4 ব্যবহার করার জন্য:
timer = Timer(timeInterval: 1, target: self, selector: #selector(timerUpdated), userInfo: nil, repeats: true)
RunLoop.main.add(timer, forMode: .common)
tl; ডাঃ রানলুপটি স্ক্রোলিং করছে যাতে এটি আর কোনও ইভেন্ট হ্যান্ডেল করতে পারে না - আপনি নিজে নিজে টাইমার সেট না করে রাখুন যাতে রানওলাপ টাচ ইভেন্টগুলি পরিচালনা করে থাকে তখনও এটি ঘটতে পারে। অথবা বিকল্প সমাধান চেষ্টা করে জিসিডি ব্যবহার করুন
কোনও আইওএস বিকাশকারীকে অবশ্যই পড়তে হবে। প্রচুর জিনিস চূড়ান্তভাবে রানলুপের মাধ্যমে কার্যকর করা হয়।
অ্যাপলের ডক্স থেকে প্রাপ্ত ।
একটি রান লুপটি এর নামের মতো শোনা যায়। এটি আপনার থ্রেডটি প্রবেশ করে এবং আগত ইভেন্টগুলির প্রতিক্রিয়ায় ইভেন্ট হ্যান্ডলারগুলি চালাতে ব্যবহার করে
কারণ আপনি যখন রান লুপটি চালান তখন টাইমার এবং অন্যান্য পর্যায়ক্রমিক ইভেন্টগুলি সরবরাহ করা হয় circum আপনি যখন লুপটি প্রবেশ করে এবং বারবার অ্যাপ্লিকেশন থেকে ইভেন্টগুলির অনুরোধ করে মাউস-ট্র্যাকিং রুটিন প্রয়োগ করেন তখনই এই আচরণের সাধারণ উদাহরণটি ঘটে। আপনার কোডটি সরাসরি ইভেন্টগুলি দখল করার কারণে অ্যাপ্লিকেশনটিকে সেই ঘটনাগুলিকে সাধারণত প্রেরণ করার পরিবর্তে সক্রিয় টাইমারগুলি আপনার মাউস-ট্র্যাকিং রুটিনটি প্রস্থান না করে এবং অ্যাপ্লিকেশনটিতে নিয়ন্ত্রণ ফিরে না পাওয়া পর্যন্ত অচল করে দিতে সক্ষম হবে।
এটি আমাদের অনেক সময় লক্ষ্য না করেই প্রচুর সময় হয়। আমি বোঝাতে চাইছি আমরা টাইমারটি 10: 10: 10: 00 তে আগুন জ্বালিয়ে দিয়েছি, তবে রানলুপ একটি ইভেন্ট চালাচ্ছে যা 10: 10: 10: 05 অবধি গ্রহণ করে, তাই টাইমারটি বহিস্কার করা হয় 10: 10: 10: 06
একইভাবে, যদি রানার লুপটি কোনও হ্যান্ডলার রুটিন সম্পাদন করার মাঝামাঝি সময়ে থাকে তবে টাইমার তার হ্যান্ডলার রুটিনটি চালানোর জন্য রান লুপের মাধ্যমে পরবর্তী সময় পর্যন্ত অপেক্ষা করে। রান লুপটি যদি চলমান না থাকে তবে টাইমার কখনই গুলি চালায় না।
আপনি একবার বা বারবার ইভেন্টগুলি তৈরি করতে টাইমারগুলি কনফিগার করতে পারেন। একটি পুনরাবৃত্তি টাইমার স্বয়ংক্রিয়ভাবে নির্ধারিত ফায়ারিং সময়ের উপর ভিত্তি করে পুনরায় সময়সীমা তৈরি করে, আসল গুলি চালানোর সময় নয়। উদাহরণস্বরূপ, যদি কোনও টাইমার নির্দিষ্ট সময়ে এবং তার পরে প্রতি 5 সেকেন্ডে গুলি চালানোর সময় নির্ধারিত হয় তবে নির্ধারিত গুলি চালানোর সময়টি সর্বদা আসল 5 দ্বিতীয় বারের বিরতিতে পড়ে যাবে, এমনকি আসল গুলির সময় দেরি হয়ে গেলেও। যদি ফায়ারিংয়ের সময়টি এত বেশি বিলম্বিত হয় যে এটি নির্ধারিত গুলি চালানোর সময়গুলির এক বা একাধিকটি মিস করে তবে টাইমার মিসড সময়সীমার জন্য কেবল একবারই চালিত হয়। মিস সময়ের জন্য গুলি চালানোর পরে, টাইমারটি পরবর্তী নির্ধারিত গুলি চালানোর সময়টির জন্য পুনরায় নির্ধারণ করা হয়।
আপনি পারবেন না। ওএস আপনার জন্য কেবল নিজেকে পরিবর্তন করে। যেমন যখন ব্যবহারকারী ট্যাপ করেন, তারপরে মোডটি স্যুইচ করে eventTracking
। ব্যবহারকারীর ট্যাপগুলি সমাপ্ত হলে মোডটি আবার ফিরে যায় default
। আপনি যদি কোনও নির্দিষ্ট মোডে চালিত করতে চান তবে তা ঘটবে তা নিশ্চিত করা আপনার পক্ষে।
যখন ব্যবহারকারী রান লুপ মোডটি স্ক্রোল করছে তখন হয়ে যায় tracking
। রানলুপ গিয়ার শিফট করার জন্য ডিজাইন করা হয়েছে। মোডটি সেট হয়ে গেলে eventTracking
, তারপরে ইভেন্টগুলি স্পর্শ করার জন্য এটি অগ্রাধিকার দেয় (মনে রাখবেন আমাদের কাছে সিপিইউ সীমাবদ্ধ রয়েছে)। এটি ওএস ডিজাইনারদের একটি আর্কিটেকচারাল ডিজাইন ।
ডিফল্টরূপে টাইমারগুলি tracking
মোডে নির্ধারিত হয় না । সেগুলি নির্ধারিত:
একটি টাইমার তৈরি করে এবং এটি ডিফল্ট মোডে বর্তমান রান লুপের সময়সূচী করে ।
scheduledTimer
নীচে এই আছে:
RunLoop.main.add(timer, forMode: .default)
আপনি যদি স্ক্রল করার সময় আপনার টাইমারটি কাজ করতে চান তবে আপনাকে অবশ্যই এটি করতে হবে:
let timer = Timer.scheduledTimer(timeInterval: 1.0, target: self,
selector: #selector(fireTimer), userInfo: nil, repeats: true) // sets it on `.default` mode
RunLoop.main.add(timer, forMode: .tracking) // AND Do this
বা কেবল করুন:
RunLoop.main.add(timer, forMode: .common)
চূড়ান্তভাবে উপরের একটিটির অর্থ হ'ল স্পর্শ ইভেন্টগুলি দ্বারা আপনার থ্রেড অবরুদ্ধ নয় । যা এর সমান:
RunLoop.main.add(timer, forMode: .default)
RunLoop.main.add(timer, forMode: .eventTracking)
RunLoop.main.add(timer, forMode: .modal) // This is more of a macOS thing for when you have a modal panel showing.
আপনি আপনার টাইমারটির জন্য জিসিডি ব্যবহারের বিষয়ে বিবেচনা করতে পারেন যা আপনাকে রান কোড লুপ পরিচালনার সমস্যা থেকে আপনার কোড "রক্ষা" করতে সহায়তা করবে।
পুনরাবৃত্তি না করার জন্য কেবল ব্যবহার করুন:
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
// your code here
}
পুনরাবৃত্তি টাইমার ব্যবহারের জন্য:
কীভাবে ডিসপ্যাচসোর্সটাইমার ব্যবহার করবেন তা দেখুন
ড্যানিয়েল জলকুতের সাথে আমার যে আলোচনা হয়েছিল তার থেকে আরও গভীর খনন:
প্রশ্ন: জিসিডি (ব্যাকগ্রাউন্ড থ্রেড) যেমন একটি ব্যাকগ্রাউন্ড থ্রেডের asyncAfter কীভাবে রানলুপের বাইরে কার্যকর হবে? এগুলি থেকে আমার বুঝতে পারা যায় যে সমস্ত কিছুই রানলুপের মধ্যে কার্যকর করা উচিত
অগত্যা নয় - প্রতিটি থ্রেডের সর্বাধিক এক রান লুপ থাকে তবে থ্রেডের "মালিকানা" কার্যকর করার সমন্বয় করার কোনও কারণ না থাকলে শূন্য থাকতে পারে।
থ্রেডগুলি একটি ওএস স্তরের সাশ্রয়ী মূল্যের মূল্য যা আপনার প্রক্রিয়াটিকে একাধিক সমান্তরাল সম্পাদন প্রসঙ্গের মধ্যে এর কার্যকারিতা বিভক্ত করার ক্ষমতা দেয়। রান লুপগুলি একটি ফ্রেমওয়ার্ক-স্তরীয় সাশ্রয়ী মূল্যের সাশ্রয় যা আপনাকে একক থ্রেডে আরও বিভক্ত করতে দেয় যাতে এটি একাধিক কোড পাথের মাধ্যমে দক্ষতার সাথে ভাগ করা যায়।
সাধারণত আপনি যদি এমন কিছু প্রেরণ করেন যা থ্রেডে চালিত হয় তবে সম্ভবত এটির রানলুপ থাকবে না যদি না এমন কিছু কল আসে [NSRunLoop currentRunLoop]
যা স্পষ্টতই একটি তৈরি করে।
সংক্ষেপে, মোডগুলি মূলত ইনপুট এবং টাইমারগুলির জন্য একটি ফিল্টার প্রক্রিয়া