অবজেক্ট-সি তে সময় কেটে যাওয়া


153

আমাকে দুটি ইভেন্টের মধ্যে সময় কাটাতে হবে, উদাহরণস্বরূপ, একটি ইউআইভিউর উপস্থিতি এবং ব্যবহারকারীর প্রথম প্রতিক্রিয়া।

আমি কীভাবে এটি উদ্দেশ্য-সি তে অর্জন করতে পারি?

উত্তর:


267
NSDate *start = [NSDate date];
// do stuff...
NSTimeInterval timeInterval = [start timeIntervalSinceNow];

timeInterval সাব-মিলিসেকেন্ড যথার্থতার সাথে সেকেন্ডে শুরু এবং এখনের মধ্যে পার্থক্য।


18
@ নিকোলাসজোজল আপনি fabs(...)একটি ফ্লোটের পরম মূল্য পেতে ব্যবহার করতে পারেন । যেমন। NSTimeInterval timeInterval = fabs([start timeIntervalSinceNow]);
সুতরাং এটি

1
সময়ের মান মনে হয় আন্তঃকালীন মানটি নেতিবাচক।
জ্যাকি

যদি আপনি একটি নেতিবাচক মান পেয়ে থাকেন - -1 দিয়ে
গুণান

10
উপর নির্ভর করে [NSDate date]ত্রুটিগুলি ট্র্যাক করতে অসুবিধা হতে পারে, আরও তথ্যের জন্য এই উত্তরটি দেখুন।
সংবেদনশীল

নিবন্ধন করুন কিভাবে বৈধভাবে একটি নেতিবাচক মান ঘটতে পারে?
টড লেহম্যান

228

[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 ফ্রেমওয়ার্ক আপনার টার্গেট এর সেটিংসে।


17
দয়া করে এটি উত্সাহিত করুন। যদিও আমি মনে করি সবাই সম্মত হতে পারে যে এনএসডিট আপনার প্রথম বিকল্প হওয়া উচিত, এই পরামর্শটি আমার একটি সমস্যা সমাধান করেছে। যখন [NSDate date]একটি প্রেরণ ব্লকের মধ্যে একটি সমাপ্তি ব্লকের মধ্যে কল করার সময় , আমি একই "বর্তমান" সময়টি পেয়ে যাচ্ছিলাম [NSDate date]মৃত্যুদন্ড কার্যকর হওয়ার আগেই আমার ব্লক তৈরি হয়েছিল এমন সময়ে আঘাত হানার আগে। CACurrentMediaTime()এই সমস্যাটি সমাধান করুন।
n00neimp0rtant 21

আমরা কীভাবে মিমি: এসএস এর মতো প্রদর্শনের জন্য বর্ধিত সময়টি ব্যবহার করব?
সাইবারমিউ


12
CACurrentMediaTime()ডিভাইস যখন ঘুমের মধ্যে প্রবেশ করে তখন টিক দেওয়া বন্ধ করে দেয় সে বিষয়ে সচেতন হন । আপনি যদি কোনও কম্পিউটার থেকে সংযোগ বিচ্ছিন্ন ডিভাইসটির সাথে পরীক্ষা করেন, এটি লক করুন, তবে 10 মিনিট অপেক্ষা করুন আপনি দেখতে পাবেন যা CACurrentMediaTime()প্রাচীর ঘড়ির সময় ধরে রাখে না।
রুশবিশপ

যোগ এবং আমদানি #import <QuartzCore / QuartzCore.h>
zoleko steveen

23

timeIntervalSinceDateপদ্ধতিটি ব্যবহার করুন

NSTimeInterval secondsElapsed = [secondDate timeIntervalSinceDate:firstDate];

NSTimeIntervalএটি কেবল একটি double, এর NSDateমতো সংজ্ঞা দিন :

typedef double NSTimeInterval;

15

আইওএসের জন্য 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;
}

মাচ_টাইমবেস_ইনফো কলটিতে কেন কোনও রিডানড্যান্ট (অকার্যকর) castালাই আছে কেউ জানেন?
সাইমন টিলসন

@ সিমোনটিলসন এটি একটি ভাল প্রশ্ন - হয় কোনও সতর্কতা নিঃশব্দ করা দরকার ছিল, অথবা আমি অন্য কোথাও থেকে এটি অনুলিপি করেছিলাম এবং কেবল এটি মুছে ফেলার বিষয়টি লক্ষ্য করি নি। মনে নেই।
ওয়েইন উরোদা

2
এটি থ্রেড নিরাপদ নয়। প্রকৃত মানগুলিতে সেট করার আগে mach_timebase_info()পাস-ইন পুনরায় সেট করবে যা একাধিক থ্রেড থেকে কোড কল করা হলে শূন্য দ্বারা বিভাজন ঘটায়। পরিবর্তে ব্যবহার করুন (বা যা সেকেন্ডে রূপান্তরিত করার জন্য ম্যাক টাইম)। mach_timebase_info_data_t{0,0}dispatch_once()CACurrentMediaTime
আশ্চর্য.মাইস

ধন্যবাদ @ আশ্চর্য.মাইস, আমি আমার উত্তর আপডেট করেছি (পরিমাণ নির্ধারণের সাথে সম্পর্কিত একটি সমস্যাও পেয়েছি, আমি 6 বছরের কম বয়সী আমাকে দোষ দিচ্ছি ...)
ওয়েইন উরোদা


4

নীচের মতো এনএসডিট ক্লাসের টাইমআইন্টারভালসিন্স 1970 ফাংশনটি ব্যবহার করুন:

double start = [startDate timeIntervalSince1970];
double end = [endDate timeIntervalSince1970];
double difference = end - start;

মূলত, এটি আমি 2 বিভিন্ন তারিখের মধ্যে সেকেন্ডের মধ্যে পার্থক্যটি তুলনা করতে ব্যবহার করি। এছাড়াও এই লিঙ্কটি এখানে দেখুন


0

অন্যান্য উত্তরগুলি সঠিক (একটি সতর্কতা সহ *)। উদাহরণটি ব্যবহার দেখানোর জন্য আমি এই উত্তরটি যুক্ত করছি:

- (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সময় যে কোনও মুহূর্তে এগিয়ে বা পিছনে লাফিয়ে উঠতে পারে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.