আমাকে দুটি ইভেন্টের মধ্যে সময় কাটাতে হবে, উদাহরণস্বরূপ, একটি ইউআইভিউর উপস্থিতি এবং ব্যবহারকারীর প্রথম প্রতিক্রিয়া।
আমি কীভাবে এটি উদ্দেশ্য-সি তে অর্জন করতে পারি?
আমাকে দুটি ইভেন্টের মধ্যে সময় কাটাতে হবে, উদাহরণস্বরূপ, একটি ইউআইভিউর উপস্থিতি এবং ব্যবহারকারীর প্রথম প্রতিক্রিয়া।
আমি কীভাবে এটি উদ্দেশ্য-সি তে অর্জন করতে পারি?
উত্তর:
NSDate *start = [NSDate date];
// do stuff...
NSTimeInterval timeInterval = [start timeIntervalSinceNow];
timeInterval
সাব-মিলিসেকেন্ড যথার্থতার সাথে সেকেন্ডে শুরু এবং এখনের মধ্যে পার্থক্য।
[NSDate date]
ত্রুটিগুলি ট্র্যাক করতে অসুবিধা হতে পারে, আরও তথ্যের জন্য এই উত্তরটি দেখুন।
[NSDate date]
সময়সীমার জন্য আপনার নির্ভর করা উচিত নয় কারণ এটি অতিবাহিত সময়কে বেশি বা কম-বেশি রিপোর্ট করতে পারে। এমন কি এমন ঘটনাও রয়েছে যেখানে আপনার কম্পিউটারটি আপাতদৃষ্টিতে সময় ভ্রমণ করতে পারে যেহেতু অতিবাহিত সময়টি নেতিবাচক হবে! (উদাহরণস্বরূপ যদি ঘড়িটি পিছনের দিকে চলে যায়))
শীতকালীন 2013 স্ট্যানফোর্ড আইওএস কোর্সের "অ্যাডভান্সড আইওএস গ্যাচার রিকগনিশন" বক্তৃতায় আরিয়া হাঘিীর মতে , (34:00) আপনার CACurrentMediaTime()
সঠিক সময় ব্যবধানের প্রয়োজন হলে আপনার ব্যবহার করা উচিত you
উদ্দেশ্য গ:
#import <QuartzCore/QuartzCore.h>
CFTimeInterval startTime = CACurrentMediaTime();
// perform some action
CFTimeInterval elapsedTime = CACurrentMediaTime() - startTime;
সুইফট:
let startTime = CACurrentMediaTime()
// perform some action
let elapsedTime = CACurrentMediaTime() - startTime
কারণটি হ'ল [NSDate date]
সার্ভারে সিঙ্ক হয়, সুতরাং এটি "টাইম-সিঙ্ক হিচাপস" এর দিকে পরিচালিত করতে পারে যা খুব অসুবিধাজনিত ট্র্যাক বাগগুলিতে নিয়ে যেতে পারে। CACurrentMediaTime()
অন্যদিকে, এমন একটি ডিভাইস সময় যা এই নেটওয়ার্ক সিঙ্কগুলির সাথে পরিবর্তিত হয় না।
আপনি করতে হবে যোগ QuartzCore ফ্রেমওয়ার্ক আপনার টার্গেট এর সেটিংসে।
[NSDate date]
একটি প্রেরণ ব্লকের মধ্যে একটি সমাপ্তি ব্লকের মধ্যে কল করার সময় , আমি একই "বর্তমান" সময়টি পেয়ে যাচ্ছিলাম [NSDate date]
মৃত্যুদন্ড কার্যকর হওয়ার আগেই আমার ব্লক তৈরি হয়েছিল এমন সময়ে আঘাত হানার আগে। CACurrentMediaTime()
এই সমস্যাটি সমাধান করুন।
CACurrentMediaTime()
ডিভাইস যখন ঘুমের মধ্যে প্রবেশ করে তখন টিক দেওয়া বন্ধ করে দেয় সে বিষয়ে সচেতন হন । আপনি যদি কোনও কম্পিউটার থেকে সংযোগ বিচ্ছিন্ন ডিভাইসটির সাথে পরীক্ষা করেন, এটি লক করুন, তবে 10 মিনিট অপেক্ষা করুন আপনি দেখতে পাবেন যা CACurrentMediaTime()
প্রাচীর ঘড়ির সময় ধরে রাখে না।
timeIntervalSinceDate
পদ্ধতিটি ব্যবহার করুন
NSTimeInterval secondsElapsed = [secondDate timeIntervalSinceDate:firstDate];
NSTimeInterval
এটি কেবল একটি double
, এর NSDate
মতো সংজ্ঞা দিন :
typedef double NSTimeInterval;
আইওএসের জন্য getTickCount () বাস্তবায়ন খুঁজছেন যে কেউ এখানে আসার জন্য, বিভিন্ন উত্স একসাথে রাখার পরে এটি আমার।
পূর্বে আমার এই কোডটিতে একটি বাগ ছিল (আমি প্রথমে 1000000 দ্বারা বিভক্ত হয়েছি) যা আমার আইফোন 6 এ আউটপুটটির কিছু পরিমাণ নির্ধারণের কারণ হয়ে দাঁড়িয়েছিল (সম্ভবত এটি আইফোন 4 / ইত্যাদিতে কোনও সমস্যা ছিল না বা আমি এটি কখনই লক্ষ্য করি নি)। মনে রাখবেন যে বিভাগটি প্রথমে সম্পাদন না করে, টাইমবেজের অঙ্কটি বেশ বড় হলে ওভারফ্লো হওয়ার কিছুটা ঝুঁকি থাকে। যদি কারও কৌতূহলী হয় তবে এখানে আরও অনেক তথ্যের সাথে একটি লিঙ্ক রয়েছে: https://stackoverflow.com/a/23378064/588476
সেই তথ্যের আলোকে, সম্ভবত অ্যাপলের ফাংশনটি ব্যবহার করা আরও নিরাপদ CACurrentMediaTime
!
আমি mach_timebase_info
কলটিও বেঞ্চমার্ক করেছি এবং এটি আমার আইফোন 6-তে আনুমানিক 19ns লাগে, তাই আমি সেই কলটির আউটপুটকে ক্যাশে করে থাকা (থ্রেডসেফ নয়) কোডটি সরিয়েছি।
#include <mach/mach.h>
#include <mach/mach_time.h>
uint64_t getTickCount(void)
{
mach_timebase_info_data_t sTimebaseInfo;
uint64_t machTime = mach_absolute_time();
// Convert to milliseconds
mach_timebase_info(&sTimebaseInfo);
machTime *= sTimebaseInfo.numer;
machTime /= sTimebaseInfo.denom;
machTime /= 1000000; // convert from nanoseconds to milliseconds
return machTime;
}
টাইমবেস কলের ফলাফলের উপর নির্ভর করে ওভারফ্লো সম্ভাব্য ঝুঁকি সম্পর্কে সচেতন হন। আমি সন্দেহ করি (তবে জানি না) এটি আইফোনের প্রতিটি মডেলের জন্য একটি ধ্রুবক হতে পারে। আমার আইফোন 6 এ ছিল 125/3
।
সমাধানটি CACurrentMediaTime()
বেশ তুচ্ছ:
uint64_t getTickCount(void)
{
double ret = CACurrentMediaTime();
return ret * 1000;
}
mach_timebase_info()
পাস-ইন পুনরায় সেট করবে যা একাধিক থ্রেড থেকে কোড কল করা হলে শূন্য দ্বারা বিভাজন ঘটায়। পরিবর্তে ব্যবহার করুন (বা যা সেকেন্ডে রূপান্তরিত করার জন্য ম্যাক টাইম)। mach_timebase_info_data_t
{0,0}
dispatch_once()
CACurrentMediaTime
পার্সেস সময় পরিমাপের জন্য (গেটটিকাউন্টের মতো), ম্যাক_অবসুলিউট_টাইম এবং এই অ্যাপল প্রশ্নোত্তর: http://developer.apple.com/qa/qa2004/qa1398.html এ একবার দেখুন ।
নীচের মতো এনএসডিট ক্লাসের টাইমআইন্টারভালসিন্স 1970 ফাংশনটি ব্যবহার করুন:
double start = [startDate timeIntervalSince1970];
double end = [endDate timeIntervalSince1970];
double difference = end - start;
মূলত, এটি আমি 2 বিভিন্ন তারিখের মধ্যে সেকেন্ডের মধ্যে পার্থক্যটি তুলনা করতে ব্যবহার করি। এছাড়াও এই লিঙ্কটি এখানে দেখুন
অন্যান্য উত্তরগুলি সঠিক (একটি সতর্কতা সহ *)। উদাহরণটি ব্যবহার দেখানোর জন্য আমি এই উত্তরটি যুক্ত করছি:
- (void)getYourAffairsInOrder
{
NSDate* methodStart = [NSDate date]; // Capture start time.
// … Do some work …
NSLog(@"DEBUG Method %s ran. Elapsed: %f seconds.", __func__, -([methodStart timeIntervalSinceNow])); // Calculate and report elapsed time.
}
ডিবাগার কনসোলে আপনি এমন কিছু দেখতে পান:
DEBUG Method '-[XMAppDelegate getYourAffairsInOrder]' ran. Elapsed: 0.033827 seconds.
* ক্যাভেট: অন্যরা যেমন উল্লেখ করেছে, NSDate
কেবল ব্যস্ত সময়কে কেবল নৈমিত্তিক উদ্দেশ্যে গণনার জন্য ব্যবহার করুন। এরকম একটি উদ্দেশ্য সাধারণ পরীক্ষা, ক্রুড প্রোফাইলিং হতে পারে, যেখানে আপনি কোনও পদ্ধতি কতটা সময় নিচ্ছেন তার মোটামুটি ধারণা চান।
ঝুঁকিটি হ'ল নেটওয়ার্ক ক্লক সিঙ্কের কারণে যে কোনও মুহুর্তে ডিভাইসের ঘড়ির বর্তমান সময়ের সেটিংটি পরিবর্তন হতে পারে। সুতরাং NSDate
সময় যে কোনও মুহূর্তে এগিয়ে বা পিছনে লাফিয়ে উঠতে পারে।
fabs(...)
একটি ফ্লোটের পরম মূল্য পেতে ব্যবহার করতে পারেন । যেমন।NSTimeInterval timeInterval = fabs([start timeIntervalSinceNow]);