রিলিজ সংস্করণ আইওএস সুইফটের জন্য মুদ্রণ () মুছে ফেলুন


84

আমি println()কোনও ডিবাগ বিল্ডে না থাকলে আমি বিশ্বব্যাপী আমার সুইফট কোডের সমস্ত কল উপেক্ষা করতে চাই । আমি এর জন্য ধাপে ধাপে কোনও শক্তিশালী পদক্ষেপ খুঁজে পাচ্ছি না এবং নির্দেশনার প্রশংসা করব। বিশ্বব্যাপী এটি করার কোনও উপায় আছে, বা বিবৃতি println()দিয়ে আমাকে প্রতিটি #IF DEBUG/#ENDIFঘিরতে হবে?



6
ডিভাইস কনসোলে আর আউটপুট প্রিন্ট করা হবে না তবে এটি ডিবাগার কনসোলে রয়েছে ... মুক্তি সংস্করণে অপসারণের দরকার নেই no
আনিস পরজুলি 웃

4
এক্সকোড 8 এবং সুইফ্ট 3 হিসাবে আমি রিলিজ মোডে কনসোলে প্রিন্ট দেখতে পাই না।
সিএনএনএন

উত্তর:


102

সবচেয়ে সহজ উপায় হ'ল আপনার নিজস্ব গ্লোবাল ফাংশনটি সুইফটের সামনে রাখুন println:

func println(object: Any) {
    Swift.println(object)
}

লগিং বন্ধ করার সময় হয়ে গেলে, কেবলমাত্র সেই ফাংশনের মূল অংশটি মন্তব্য করুন:

func println(object: Any) {
    // Swift.println(object)
}

অথবা আপনি শর্তযুক্ত ব্যবহার করে এটি স্বয়ংক্রিয়ভাবে তৈরি করতে পারেন:

func println(object: Any) {
    #if DEBUG
        Swift.println(object)
    #endif
}

সম্পাদনা ইন সুইফট ২.০ printlnএ পরিবর্তন করা হয়েছে print। দুর্ভাগ্যক্রমে এটির এখন একটি বৈকল্পিক প্রথম প্যারামিটার রয়েছে; এটি দুর্দান্ত, তবে এর অর্থ আপনি সহজেই এটিকে ওভাররাইড করতে পারবেন না কারণ সুইফ্টের কোনও "স্প্ল্যাট" অপারেটর নেই সুতরাং আপনি কোডে কোনও ভেরিয়েডিক পাস করতে পারবেন না (এটি কেবল আক্ষরিক অর্থে তৈরি করা যেতে পারে)। তবে আপনি একটি হ্রাস করা সংস্করণ তৈরি করতে পারেন যা কার্যকরভাবে কাজ করে যদি সাধারণত হয়, আপনি কেবল একটি মান মুদ্রণ করছেন:

func print(items: Any..., separator: String = " ", terminator: String = "\n") {
    Swift.print(items[0], separator:separator, terminator: terminator)
}

সুইফ্ট 3 এ আপনাকে প্রথম প্যারামিটারের বাহ্যিক লেবেলটি দমন করতে হবে:

func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
    Swift.print(items[0], separator:separator, terminator: terminator)
}

4
সুন্দর সমাধান, ধন্যবাদ। আমাকে বলা হয়েছে যে আইওএসে (তবে ওএস এক্স নয়) println()রিলিজ মোডে কার্যকর হয় না।
নাট বিরখোলজ

13
@ নাটবিরখোলজ না, এটি বোকামি। (তিনি বলেছেন, এটি নিশ্চিত করার জন্য পরীক্ষার পরে!)
ম্যাট

সুইফট 2-এ, মুদ্রণের জন্য ফাংশনটির নতুন নামকরণ করা হয়েছে, আপনি কি কেবল মজা করার সুযোগ পাবেন? এছাড়াও, আপনি কীভাবে এটি বিশ্বব্যাপী সংজ্ঞায়িত করবেন? আমি এটিকে আমার ক্লাসের বাইরে অ্যাপডেলিগেটে রাখার চেষ্টা করেছি এবং আমার এক মিলিয়ন মুদ্রণ () কল থাকলেও এটি কখনও কল করা হয় না। আমি যা চেষ্টা করেছি তা এখানে: ফানক মুদ্রণ (অবজেক্ট: যে কোনও) {সুইফট.প্রিন্ট (অবজেক্ট)}
চার্লি

@ চর্লি হ্যাঁ, আমি এখনও এটিকে printlnপরিবর্তিত হয়ে ব্যবহার করছি print। এটি আপনার পক্ষে কাজ না করার কারণটি হ'ল আপনার printসংজ্ঞাটি সুইফটের সাথে মেলে না, তাই আপনি এটিকে ওভাররাইড করছেন না। একটি সামান্য সমস্যা আছে কারণ, যেমনটি অনেকবার মন্তব্য করা হয়েছে, সুইফ্টের কোনও স্প্ল্যাট অপারেটর নেই, সুতরাং আপনি বৈকল্পিকটি পাস করতে পারবেন না। তবে এটি একটি আইটেমের জন্য দুর্দান্ত কাজ করে, যা আপনি পাস করতে পারেন items[0]
ম্যাট

4
আপনি যদি এই লগ স্টেটমেন্টগুলি কোডের উচ্চ কার্যকারিতা বিভাগগুলিতে সন্নিবেশ করিয়ে থাকেন তবে এখানে একটি সতর্কতা: সুইফট তখনও স্ট্রিং ইন্টারপোলেশন এবং রেন্ডারিং পরামিতিগুলিতে ফাংশনে যেতে সময় ব্যয় করবে, এমনকি যদি সেগুলি ব্যবহার না করা হয়। শর্তসাপেক্ষে বিবৃতিগুলি সরানোর একমাত্র উপায় হ'ল পতাকাটিতে তাদের ভবিষ্যদ্বাণী করা। উদাহরণস্বরূপ যদি (লগ) {মুদ্রণ (..) প্রতিটি স্থানে যেখানে তারা ব্যবহৃত হয়}
প্যাট নিমিমায়ার

48

সুইফট 4.x এর জন্য আপডেট হয়েছে:

সুইট 2.0 / 3.0 এবং এক্সকোড 7/8 এখন বিটা ছাড়াই, আপনি কীভাবে মুক্তির বিল্ডগুলিতে মুদ্রণ ফাংশনটি অক্ষম করবেন তাতে কিছু পরিবর্তন হয়েছে।

উপরে @ ম্যাট এবং @ নেট বীরখোল্জের দ্বারা উল্লেখ করা কয়েকটি গুরুত্বপূর্ণ বিষয় রয়েছে যা এখনও কার্যকর।

  1. println()ফাংশন দ্বারা প্রতিস্থাপিত করা হয়েছেprint()

  2. #if DEBUG ম্যাক্রোটি ব্যবহার করার জন্য আপনাকে মানটি রাখতে "সুইফ্ট সংকলক - কাস্টম ফ্ল্যাগস - অন্য পতাকাগুলি" সংজ্ঞায়িত করতে হবে-D DEBUG

  3. আমি Swift.print()গ্লোবাল স্কোপটিতে ফাংশনটিকে ওভাররাইড করার প্রস্তাব দিচ্ছি যাতে আপনি আপনার কোডটিতে print()ফাংশনটি স্বাভাবিক হিসাবে ব্যবহার করতে পারেন তবে এটি ডিবাগ-বিল্ডগুলির জন্য আউটপুট সরিয়ে ফেলবে। এখানে একটি ফাংশন স্বাক্ষর যা আপনি বিশ্বব্যাপী স্কোপটিতে সুইফট ২.০ / 3.0.০ এ যোগ করতে পারেন:

    func print(items: Any..., separator: String = " ", terminator: String = "\n") {
    
        #if DEBUG
    
        var idx = items.startIndex
        let endIdx = items.endIndex
    
        repeat {
            Swift.print(items[idx], separator: separator, terminator: idx == (endIdx - 1) ? terminator : separator)
            idx += 1
        }
        while idx < endIdx
    
        #endif
    }
    

দ্রষ্টব্য: আমরা এখানে একটি স্থান হিসাবে ডিফল্ট বিভাজক এবং ডিফল্ট টার্মিনেটরটিকে একটি নতুন লাইন হিসাবে সেট করেছি। আপনি যদি চান তবে আপনার প্রকল্পে এটি আলাদাভাবে কনফিগার করতে পারেন।

আশাকরি এটা সাহায্য করবে.

হালনাগাদ:

এই ফাংশনটি বিশ্বব্যাপী স্কোপ এ রাখা সাধারণত পছন্দনীয়, যাতে এটি সুইফটের সামনে বসে print ফাংশনের । আমি দেখতে পেয়েছি যে এটির আয়োজনের সর্বোত্তম উপায় হ'ল আপনার প্রকল্পে কোনও ইউটিলিটি ফাইল যুক্ত করা (যেমন ডিবাগঅপশনস সুইট) আপনি যেখানে এই ফাংশনটি বিশ্বব্যাপী সুযোগে রাখতে পারেন।

সুইফ্ট 3-এর হিসাবে ++অপারেটর অবচয় করা হবে। এই পরিবর্তনটি প্রতিবিম্বিত করতে আমি উপরে স্নিপেট আপডেট করেছি।


4
আমি দুঃখিত, তবে কোথায় ফাংশন রাখব?
DàCh Octn

@ ব্যবহারকারী 9527 সম্ভবত আপনি এটি বিশ্বব্যাপী কোনও জায়গায় রেখে দিতে চান, যাতে এটি আপনার প্রকল্পের সর্বত্র অ্যাক্সেসযোগ্য। আমার প্রকল্পগুলিতে, আমি একটি ইউটিলিটি সুইফ্ট ফাইল (ডিবাগঅপশনসইউফিট বা অনুরূপ কিছু) যুক্ত করি এবং এই ফাংশনটি বিশ্বব্যাপী স্কোপে রাখি (অর্থাত্ কোনও বদ্ধ শ্রেণিতে নয়)।
গ্লাভিড

আপনি কী সুইফট-এক্সকোডের বর্তমান সংস্করণ হিসাবে নিশ্চিত করতে পারবেন, মুদ্রণ বিবরণী -D ডিবাগ ফ্ল্যাট সেট করার কোনও প্রয়োজন ছাড়াই ডিভাইস কনসোলে আর আউটপুট আসবে না? অন্তত আমি আজ এটি পরীক্ষা করেছি have
ব্যবহারকারী523234

4
সুইফ্ট 3 হিসাবে, যুক্তিগুলির তালিকার শুরুতে আন্ডারস্কোর যুক্ত করে কেউ আরও কিছুটা বর্বরতা পেতে পারেন: "মুদ্রণ (_ আইটেম ..."
জোনাথন ঝাঁ

8
সুতরাং আমি মুদ্রণের রেফারেন্সটি অনুসন্ধান করেছি (ডডফিনিশল্যাঞ্চিংয়ে ব্যবহৃত ...) এবং এটি আমাকে মূল মুদ্রণ ফাংশন সুইফ্টের দিকে ইঙ্গিত করেছিল। এটি এবং @ জোনাথনজাহানের মন্তব্যকে একত্রে রেখে আমি ফাংশনটিকে এটির মতো করে সামঞ্জস্য করেছি এবং ভয়েলা এটি কাজ করে:public func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
জনি

38

আমার সহ এই সমস্ত পদ্ধতির সমস্যা হ'ল তারা printআর্গুমেন্টগুলি মূল্যায়নের ওভারহেড সরিয়ে দেয় না । আপনি তাদের মধ্যে কোনটি ব্যবহার করুন না কেন, এটি ব্যয়বহুল হতে চলেছে:

print(myExpensiveFunction())

একমাত্র শালীন সমাধান হ'ল আসল প্রিন্ট কলটি শর্তসাপেক্ষ সংকলনে আবদ্ধ করা (আসুন ধরে নেওয়া যাক যে DEBUGকেবলমাত্র ডিবাগ বিল্ডগুলির জন্য সংজ্ঞায়িত):

#if DEBUG
print(myExpensiveFunction())
#endif

এটি এবং কেবল এটিই, myExpensiveFunctionরিলিজ বিল্ডে ডাকা থেকে বাধা দেয় ।

তবে অটোক্লোজার ব্যবহার করে আপনি মূল্যায়নের এক স্তরকে পিছনে ফেলতে পারেন । সুতরাং, আপনি আমার সমাধানটি এটি আবার লিখতে পারেন (এটি হ'ল সুইফট 3):

func print(_ item: @autoclosure () -> Any, separator: String = " ", terminator: String = "\n") {
    #if DEBUG
    Swift.print(item(), separator: separator, terminator: terminator)
    #endif
}

আপনি কেবল একটি জিনিস মুদ্রণ করছেন এমন ক্ষেত্রে এটি সমস্যার সমাধান করে যা সাধারণত সত্য। এটি কারণ item()রিলিজ মোডে বলা হয় না। print(myExpensiveFunction())সুতরাং ব্যয়বহুল হয়ে যায় না, কারণ কলটি মূল্যায়ন না করেই বন্ধ করে গুটিয়ে দেওয়া হয়, এবং রিলিজ মোডে, এটি মোটেও মূল্যায়ন করা হবে না।


কি ব্যবহার @autoclosure?
কেলিন

আপনার বইটিতে @ ম্যাট, আপনি উল্লেখ করেছেন "মুদ্রণের একটি গুরুত্বপূর্ণ বৈশিষ্ট্য হ'ল অ্যাপ্লিকেশনটি এক্সকোডের মাধ্যমে স্বাধীনভাবে চালু করা হলে এটি কার্যকরভাবে দমন করা হয়", এর অর্থ কি আমরা আজকাল আমাদের জমা দেওয়া অ্যাপগুলিতে আমাদের মুদ্রণ বিবরণী ছেড়ে দিতে পারি, বা আমি ভুল বোঝাবুঝি করছি? কিছু?
লুকানো-ব্যবহারকারীর নাম

@ লুকানো-ব্যবহারকারীর নাম হ্যাঁ, আমি printআমার শিপিং কোডে আমার বক্তব্যগুলি রাখার ঝোঁক রাখি , তবে আমার উত্তরটি এখানে যা তা থেকে আলাদা। printআপনার এক্সকোড-ইন্ডিপেন্ডেন্ট রিলিজ বিল্ডে একটি বিবৃতি আউটপুট কনসোলে প্রেরণ করা হয়নি, তবে এটি এখনও মূল্যায়ন করা হয় , সুতরাং এটি ব্যয়বহুল বা অবাঞ্ছিত পার্শ্ব প্রতিক্রিয়া থাকলে কেবল সেই মূল্যায়ন কীভাবে দমন করতে হবে তা জানা দরকারী remains
ম্যাট

@ ম্যাট ওহ ওকে ... হ্যাঁ আমি এটি ভুল বুঝেছি। আমি তাদের মন্তব্য করব। ধন্যবাদ
লুকানো-ব্যবহারকারীর নাম

এই পদ্ধতির বাইনারি ফাইল থেকে মুদ্রিত স্ট্রিং অপসারণ করা হবে? উদাহরণস্বরূপ যদি আমি সেই পদ্ধতিটি ব্যবহার করি এবং আমার অ্যাপে কোথাও আমি "মুদ্রণ (" ব্যবহারকারী লগ ইন ")" রেখেছি এবং তারপরে কেউ যদি আমার অ্যাপ্লিকেশন প্রকৌশলীকে বিপরীত করার চেষ্টা করে তবে সে এই স্ট্রিংটি কোথাও খুঁজে পাবে বা এটি আদৌ থাকবে না?
লেসেক জাজারি

18

যেমনটি উল্লেখ করা হয়েছে, আমি একজন শিক্ষার্থী এবং কিছু অনুসরণ করার জন্য আরও কিছু পরিষ্কারভাবে সংজ্ঞায়িত জিনিসগুলির প্রয়োজন। প্রচুর গবেষণার পরে, আমার যে ক্রমটি অনুসরণ করা দরকার তা হ'ল:

এক্সকোড প্রকল্প উইন্ডোর বামে ফাইল নেভিগেটরের শীর্ষে প্রকল্পের নামের উপর ক্লিক করুন। এই প্রকল্পটির নাম, সেখানে কতগুলি বিল্ড টার্গেট রয়েছে এবং আইওএস এসডিকে সংস্করণ রয়েছে এমন লাইন।

বিল্ড সেটিংস ট্যাবটি চয়ন করুন এবং নীচে অবস্থিত " সুইফ্ট সংকলক - কাস্টম ফ্ল্যাগস " বিভাগে স্ক্রোল করুন । অন্যান্য পতাকাগুলির পাশে ডাউন তীরটি ক্লিক করুনবিভাগটি প্রসারিত ।

এটি নির্বাচন করতে ডিবাগ লাইনে ক্লিক করুন । আপনার মাউস কার্সারটিকে লাইনের ডানদিকে রেখে ডাবল ক্লিক করুন। একটি তালিকা ভিউ প্রদর্শিত হবে। ক্লিক করুন +একটি মান যুক্ত করতে তালিকার ভিউয়ের নীচে বামে বোতামটি করুন। একটি পাঠ্য ক্ষেত্র সক্রিয় হয়ে উঠবে।

পাঠ্য ক্ষেত্রে, পাঠ্য প্রবেশ করুন -D DEBUGএবং রিটার্ন টিপুন লাইনের প্রতিশ্রুতিবদ্ধ করতে ।

আপনার প্রকল্পে একটি নতুন সুইফ্ট ফাইল যুক্ত করুন। আপনি ফাইলটির জন্য একটি কাস্টম ক্লাস তৈরি করতে চাইছেন, সুতরাং নীচের লাইনের সাথে পাঠ্য প্রবেশ করুন:

class Log {

  var intFor : Int

  init() {
    intFor = 42
   }

  func DLog(message: String, function: String = __FUNCTION__) {
    #if DEBUG
      println("\(function): \(message)")
    #endif
  }
}

ক্লাসটি আজ এক্সকোড দ্বারা গৃহীত হতে পেরে আমার সমস্যা হয়েছিল, তাই উদ্যোগটি প্রয়োজনের তুলনায় কিছুটা বেশি ভারী ওজন হতে পারে।

এখন println()প্রতিটি প্রযোজ্য ক্লাসে সম্পত্তি হিসাবে এটি যুক্ত করার পরিবর্তে নতুন কাস্টম ফাংশনটি ব্যবহার করার উদ্দেশ্যে আপনি যে শ্রেণিতে নতুন কাস্টম ফাংশনটি ব্যবহার করতে চান তাতে আপনার কাস্টম ক্লাসটি উল্লেখ করতে হবে :

   let logFor = Log()

এখন আপনি কোন দৃষ্টান্ত প্রতিস্থাপন করতে পারেন println()সঙ্গেlogFor.DLog() । আউটপুটটিতে ফাংশনটির নামও অন্তর্ভুক্ত রয়েছে যেখানে রেখাটি বলা হয়েছিল।

নোট করুন যে শ্রেণীর ফাংশনগুলির অভ্যন্তরে আমি ফাংশনটি কল করতে পারি না যদি না আমি class শ্রেণীর ক্লাস ফাংশন হিসাবে ফাংশনের অনুলিপি তৈরি করি এবং println()ইনপুটটির সাথে কিছুটা নমনীয়ও থাকি, তাই প্রতিটি ক্ষেত্রেই আমি এটি ব্যবহার করতে পারি না আমার কোড


8
ডিবাগ লগের জন্য কাস্টম ক্লাস তৈরি করার দরকার নেই। এটি একটি বিশ্বব্যাপী ফাংশন ব্যবহার করা সহজ এবং আরও ব্যবহারিক।
ভোজটেক ভ্রবকা

ইনটফোর = 42 ব্যবহার কী?
টেড

16

সুইফট 5

আপনার প্রকল্পে কেবল একটি নতুন ফাইল তৈরি করুন এবং এই কোডটি এতে আটকান:

func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
    #if DEBUG
    items.forEach {
        Swift.print($0, separator: separator, terminator: terminator)        
    }
    #endif
}

এই ফাংশন স্বাক্ষরটি ডিফল্ট সুইফটটির সাথে মেলে তাই এটি আপনার প্রকল্পের ফাংশনটিকে "ওভাররাইট" করে। প্রয়োজনে আপনি এখনও ব্যবহার করে মূল অ্যাক্সেস করতে পারেন Swift.print()

একবার আপনি উপরের কোডটি যুক্ত করলে, print()যথারীতি ব্যবহার করতে থাকুন এবং এটি কেবল ডিবাগ বিল্ডগুলিতে মুদ্রণ করা হবে।

দ্রষ্টব্য: forEachপ্রতিটি আইটেম মুদ্রণ করতে করতে মুদ্রণ বিবৃতিগুলির চারপাশে বিরক্তিকর অ্যারে বন্ধনীগুলি থেকে মুক্তি পাওয়া যায় যা দেখায় যে আপনি যদি itemsসরাসরি সরাসরি প্রবেশ করেন তবেSwift.print()

সুইফটে অপেক্ষাকৃত নতুন যে কারও জন্য আপনি ভাবতে পারেন হ্যাকটি $0কী। এটি কেবলমাত্র প্রথম যুক্তিকে forEachব্লকে পাস করে উপস্থাপন করে । forEachবিবৃতি এই মত লেখা যেতে পারে:

items.forEach { item in
    Swift.print(item, separator: separator, terminator: terminator)        
}

শেষ পর্যন্ত যদি আপনি আগ্রহী হন, স্যুইফ্ট ঘোষণাটি এর printমতো দেখাচ্ছে:

public func print(_ items: Any..., separator: String = " ", terminator: String = "\n")

উপরের আমার উত্তরটি সঠিক সুইফ্ট বাস্তবায়নকে আয়না করে - যদিও আমি কখনও একের বেশি জিনিস প্রিন্ট করি না বা বিভাজক / টার্মিনেটর পরিবর্তন করি। তবে কে জানে, আপনি চাইবেন।


4
কোথায় এই ফাংশনটি ডিক্লেয়ার করবেন, এটি কি কিছু এক্সটেনশন বা এটির মতো স্মার্ট? আমি কেবল প্রতিটি ফাইলে এটি প্রকাশ করতে চাই না)
মাত্রোসোভ আলেকজান্ডার

4
@ ম্যাট্রোসোভ অ্যালেক্সান্দার আপনি কেবল আপনার অ্যাপ্লিকেশন প্রকল্পের যে কোনও জায়গায় একটি সুইফ্ট ফাইল তৈরি করতে পারেন এবং এই কোডটি রাখতে পারেন The সংকলকটি এটি বিশ্বব্যাপী অ্যাক্সেসযোগ্য করার জন্য যথেষ্ট স্মার্ট।
ট্রেভ

11

আমি এখানে একটি ফাংশন ব্যবহার করছি যা সুইফট 3 এ পুরোপুরি কাজ করে:

func gLog<T>( _ object: @autoclosure() -> T, _ file: String = #file, _ function: String = #function, _ line: Int = #line)
    {
    #if DEBUG
        let value = object()
        let stringRepresentation: String

        if let value = value as? CustomDebugStringConvertible
            {
            stringRepresentation = value.debugDescription
            }
        else if let value = value as? CustomStringConvertible
            {
            stringRepresentation = value.description
            }
        else
            {
            fatalError("gLog only works for values that conform to CustomDebugStringConvertible or CustomStringConvertible")
            }

        let fileURL = NSURL(string: file)?.lastPathComponent ?? "Unknown file"
        let queue = Thread.isMainThread ? "UI" : "BG"
    let gFormatter = DateFormatter()
    gFormatter.dateFormat = "HH:mm:ss:SSS"
        let timestamp = gFormatter.string(from: Date())

        print("✅ \(timestamp) {\(queue)} \(fileURL) > \(function)[\(line)]: " + stringRepresentation + "\n")
    #endif
    }

এটি উত্পাদিত আউটপুটটির উদাহরণ এখানে রয়েছে:

আউটপুট স্ক্রিনশট

ব্যাখ্যা:

  • সবুজ চেকমার্কটি আপনাকে কনসোলে আপনার মুদ্রণ (gLog) বার্তাগুলি দ্রুত দেখার জন্য সক্ষম হয়, যেখানে তারা কখনও কখনও অন্য বার্তাগুলির সমুদ্রে হারিয়ে যেতে পারে can

  • সময় / তারিখ স্ট্যাম্প

  • যে থ্রেডটি চলছে সেগুলি - আমার ক্ষেত্রে এটি হয় হয় মেইনথ্রেড (যা আমি ইউআই বলে ডাকি), না মেইনথ্রেড (যা আমি বিজি বলেছি, পটভূমির থ্রেডের জন্য)

  • gLog বার্তাটি থাকা ফাইলটির নাম

  • gLog বার্তাটি যে ফাইলটির মধ্যে থাকে সেটির মধ্যে ফাংশন

  • gLog বার্তার লাইন নম্বর

  • প্রকৃত gLog বার্তাটি আপনি মুদ্রণ করতে চান

আশা করি এটি অন্য কারও কাজে লাগবে!


এটিকে সমস্ত অ্যাপ্লিকেশন জুড়ে আলাদা আলাদা ফাইলে রেখে দেওয়া যেতে পারে? ক্লাস পদ্ধতি হিসাবে আমি এটি একটি পৃথক শ্রেণীর ফাইলের মধ্যে রাখার চেষ্টা করেছি। তবে এটি liMMobileGestalt MobileGestaltSupport.m: 153: pid 2574 (ডেমো) -এর সাথে স্যান্ডবক্স অ্যাক্সেস নেই এবং libMobileGestalt MobileGestalt.c: 550: ইনভার্সডেডিআরআইডি 55> অ্যাক্সেস নেই << ) ডিবাগার থেকে বার্তা: মেমরি ইস্যুর কারণে সমাপ্ত
ওমারেজো

ওমরজো, আমি আমার অ্যাপ্লিকেশন জুড়ে এটি একটি বিশ্বব্যাপী ফাংশন হিসাবে ব্যবহার করি। কোন শ্রেণির প্রয়োজন হয় না। আমার কাছে ইউস.সুইফ্ট নামে একটি ফাইল রয়েছে, এতে আমার সমস্ত ইউটিলিটি ফাংশন রয়েছে, যেমন। আপনার কেবলমাত্র ফাউন্ডেশনটি আমদানি করতে হবে তা নিশ্চিত করতে হবে - সম্ভবত আপনি যে পদক্ষেপটি হাতছাড়া করেছেন তা সম্ভবত? যাইহোক, ক্লাসের মধ্যে আপনার ফাংশনগুলি ঘোষণা করার বিষয়ে আরও তথ্যের জন্য, ক্লাসের মধ্যে স্থির ফাংশন হিসাবে বা বৈশ্বিক ফাংশন হিসাবে, এই এসও প্রশ্ন ও উত্তর দেখুন: stackoverflow.com/questions/30197548/...
জিন Loparco

হ্যাঁ, ভিতরে ফাংশনটি দিয়ে একটি নতুন ফাইল তৈরি করে এটি কাজ করেছে। কোনও কারণে এটি ক্লাস ফাংশন হিসাবে থাকার ফলে কোনও স্পষ্ট ডিবাগ বার্তা না দিয়ে অ্যাপটি ক্র্যাশ হবে।
ওমারেজো

এই লোকটির জন্য ধন্যবাদ, লজ্জা আমি এটি আগে আবিষ্কার করি নি। আমাকে অনেক ডিবাগিং মাথা ব্যাথা বাঁচিয়েছে।
বিউওল্ফ

আমার আনন্দ
জিন লোপারকো

9

সুইফট 2.1 এবং এক্সকোড 7.1.1 এর সাথে পরীক্ষিত T

রিলিজ সংস্করণগুলি থেকে সমস্ত মুদ্রণ বিবরণী বাদ দেওয়ার একটি সহজ উপায় আছে, আপনি যখন জানলেন যে সুইফট সংকলক দ্বারা খালি ফাংশনগুলি সরানো হয়েছে

সাইড নোট: উদ্দেশ্য সি যুগ, একটি প্রাক পার্সার যা আগে কম্পাইলার, লাথি আমার উত্তর বর্ণিত মত NSLog বিবৃতি মুছে ফেলার জন্য ব্যবহার করা যেতে পারে ছিল এখানে । তবে যেহেতু সুইফ্টের আর প্রি পার্সার নেই তাই এই পদ্ধতির আর বৈধতা নেই।

রিলিজ বিল্ডগুলিতে এটি অপসারণের বিষয়ে চিন্তা না করেই আমি আজ একটি উন্নত এবং সহজেই কনফিগারযোগ্য লগ ফাংশন হিসাবে যা ব্যবহার করি তা এখানে। এছাড়াও বিভিন্ন সংকলক পতাকা সেট করে, আপনি প্রয়োজনীয় হিসাবে লগ ইন করা তথ্য টুইঙ্ক করতে পারেন।

আপনি প্রয়োজন মতো ফাংশনটি টুইঙ্ক করতে পারেন, এটির উন্নতি করার জন্য কোনও পরামর্শ স্বাগত!

// Gobal log() function
//
// note that empty functions are removed by the Swift compiler -> use #if $endif to enclose all the code inside the log()
// these log() statements therefore do not need to be removed in the release build !
//
// to enable logging
//
// Project -> Build Settings -> Swift Compiler - Custom flags -> Other Swift flags -> Debug
// add one of these 3 possible combinations :
//
//      -D kLOG_ENABLE
//      -D kLOG_ENABLE -D kLOG_DETAILS
//      -D kLOG_ENABLE -D kLOG_DETAILS -D kLOG_THREADS
//
// you can just call log() anywhere in the code, or add a message like log("hello")
//
func log(message: String = "", filePath: String = #file, line: Int = #line, function: String = #function) {
            #if kLOG_ENABLE

            #if kLOG_DETAILS

            var threadName = ""
            #if kLOG_THREADS
                threadName = NSThread.currentThread().isMainThread ? "MAIN THREAD" : (NSThread.currentThread().name ?? "UNKNOWN THREAD")
                threadName = "[" + threadName + "] "
            #endif

            let fileName = NSURL(fileURLWithPath: filePath).URLByDeletingPathExtension?.lastPathComponent ?? "???"

            var msg = ""
            if message != "" {
                msg = " - \(message)"
            }

            NSLog("-- " + threadName + fileName + "(\(line))" + " -> " + function + msg)
        #else
            NSLog(message)
        #endif
    #endif
}

আপনি এখানে সংকলক পতাকা সেট করেছেন:

এখানে চিত্র বর্ণনা লিখুন

সমস্ত পতাকা সহ একটি উদাহরণ আউটপুট এর মতো দেখাচ্ছে:

   2016-01-13 23:48:38.026 FoodTracker[48735:4147607] -- [MAIN THREAD] ViewController(19) -> viewDidLoad() - hello

লগ সহ কোডটি () এর মতো দেখাচ্ছে:

    override func viewDidLoad() { log("hello")
    super.viewDidLoad()

   // Handle the text field's user input through delegate callbacks
   nameTextField.delegate = self
}

সুন্দর! আমি এটি এখান থেকে নিয়ে এসে শেষ পর্যন্ত এএলওগ এবং এইসনসোল তৈরি করেছি
tadija

এটি DEBUG মোডে কাজ করছে। এখন, আমি সম্পাদনা স্কিম থেকে রিলেস মোডে পরিবর্তন করেছি। এটি রিলিজ মোডের জন্য লগ ইন কনসোল উইন্ডোও দেখায়। কেন এমন?
জয়প্রকাশ দুবে

এক্সকোড 9-এ সুইফ্ট 3.2-র জন্য আমাকে লগ (বার্তা: "হ্যালো") মুদ্রণ করতে এবং কল করার জন্য এনএসএলগ পরিবর্তন করতে হবে, এছাড়াও আমাকে "-D" "কেএলজি_এএনএবিএল" হিসাবে বরাত দিয়ে পতাকা লাগাতে হয়েছিল। অন্যান্য সমস্ত সুইফ্ট সংস্করণ আপডেটগুলি প্রস্তাবিত সংশোধনগুলি সহ সংকলক দ্বারা গ্রহণ করা হয়েছিল।
আইসিবারপল

4
আপনি এখানে "খালি ফাংশনগুলি সুইফ্ট সংকলক দ্বারা মুছে ফেলা হয়েছে" উল্লেখ করেছেন, দস্তাবেজে আমরা কোথায় এটি পাই? আপনি কীভাবে জানেন যে ঘটনাটি? @ রনি-ওয়েবার্স
জুমজুম

7

এমনকি সহজ, ডিবিগ বিল্ড সেটিংসের -D DEBUGজন্য নিশ্চিত হওয়ার পরেও OTHER_SWIFT_FLAGS:

#if !DEBUG
    func print(_ items: Any..., separator: String = " ", terminator: String = "\n") { }
#endif

আমার সন্দেহ হয় যে এটিতে "যেখানে" দরকার হতে পারে যেহেতু মুদ্রণযোগ্য অবজেক্টগুলি ডাব্লুডাব্লুডিসির ভিডিতে খুব কমই উল্লিখিত দেখতে পান এবং সিস্টেমের প্রোটোকলের সাথে সামঞ্জস্য হয়, এবং আমি মনে করি সুইফট গাইড (গুলি) এর শেষে 1.2 বনাম 2, সেখানে পার্থক্যটি ভুলে গেছি সিস্টেমের সাথে এক
স্টিফেন জে

এখনও পর্যন্ত এটি সুইফট ১.২ নিয়ে কাজ করে। ২.০ চেষ্টা করেনি।
রিভেরা

6

এক্সকোড 8 কয়েকটি নতুন বিল্ড সেটিংস উপস্থাপন করেছে
বিশেষত যার সাথে উল্লিখিত হয়েছে অন্য ফ্ল্যাগ সেটিংস Active Compilation Conditionsযা করেছে একইভাবে তা করে does

"অ্যাক্টিভ সংকলন শর্তাবলী" সুইফট সংকলকটিতে শর্তসাপেক্ষ সংকলন পতাকাগুলি প্রেরণের জন্য একটি নতুন বিল্ড সেটিংস setting

এক্সকোড ৮ অনুসারে (৮.৩.২ এ পরীক্ষিত) আপনি এটি ডিফল্টরূপে পাবেন:

এখানে চিত্র বর্ণনা লিখুন

সুতরাং কোনও কনফিগার ছাড়াই আপনি নিম্নলিখিত লিখতে পারেন:

#if DEBUG
    print("⚠️ Something weird happened")
#endif

আমি আপনাকে দৃ strongly়ভাবে প্রস্তাব দিচ্ছি যে আপনি যদি এই পদ্ধতিটি ব্যাপকভাবে ব্যবহার করেন তবে এই শ্রেণিবদ্ধ / কাঠামো / ফাংশন তৈরি করুন যা এই লগিংয়ের যুক্তিগুলিকে আবৃত করে। আপনি আরও রাস্তায় এটি প্রসারিত করতে চাইতে পারেন।


4

বরুণ নাহারিয়ার এখন পর্যন্ত আরও ভাল সমাধান রয়েছে। আমি তার উত্তরটি রিভেরার সাথে একত্রিত করব ...

  1. -D DEBUGসংকলক নির্দেশিকায় একটি পতাকা তৈরি করুন, সেটিংস তৈরি করুন।
  2. তারপরে এই কোডটি যুক্ত করুন:

    #if !DEBUG
     public func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
    }
    #endif
    

এই কোডটি printমুক্তির জন্য প্রত্যেককে কিছুইতে রূপান্তরিত করবে না।


3

সুইফ্ট 4 এক্সকোড 10.0

সম্ভবত আপনি এটি ব্যবহার করতে পারে

func dPrint(_ message: @autoclosure () -> Any) {
    #if DEBUG
    print(message())
    #endif
}

ব্যবহারের কারণ @autoclosure হ'ল আপনি যদি বার্তা প্যারামিটার হিসাবে কোনও ফাংশনটি পাস করেন তবে ফাংশনটি কেবলমাত্র ডিবাগ মোডে ডাকা হবে, এটি কার্যকারিতা হিট করবে।

Swift.print(_ items: Any..., separator: String = default, terminator: String = default)ফাংশনটির বিপরীতে , আমার সমাধানটির একটি মাত্র প্যারামিটার রয়েছে, কারণ বেশিরভাগ ক্ষেত্রে, আমরা একাধিক পরামিতিগুলি পাস করি না কারণ মুদ্রণ ফাংশনটি কেবল কনসোলে তথ্য দেখায়, আমরা কেবলমাত্র প্যারামিটারগুলিকে স্ট্রিংয়ে রূপান্তর করতে পারি: তাই "\(param1)"+"\(param2)"না? আপনি আমার সমাধান পছন্দ করি আশা করি


1

আপনি একটি ব্রেকপয়েন্টও ব্যবহার করতে পারেন, মূল্যায়ন শেষে চালিয়ে যেতে সেট করুন এবং ব্রেকপয়েন্টে মুদ্রণ বার্তাটি লিখতে পারেন!

এখানে চিত্র বর্ণনা লিখুন


0

কার debug_printlnবিষয়বস্তু মোটামুটি হবে তা আপনি নির্ধারণ করতে পারেন:

#if DEBUG
  println()
#endif

ধন্যবাদ, আমি কোথায় এটি সর্বোত্তম সংজ্ঞা দিতে পারি? আমি এমন এক ছাত্র, যা আমি ভীত এবং আমি এর সাহায্যের প্রশংসা করি তবে আরও স্পষ্ট প্রসঙ্গে প্রয়োজন।
নাতে বীরখোলজ

আপনি এটি একটি শিরোলেখ ফাইলটিতে ঘোষণা করবেন যে আপনি যে কোনও জায়গায় এটি ব্যবহার করতে চাইলে আমদানি করবেন।
ইয়ান ম্যাকডোনাল্ড

0

আমার সমাধান ক্লাসের আগে অ্যাপডেলিগেটে এই কোডটি ব্যবহার করবে

// Disable console log in live app
#if !arch(x86_64) && !arch(i386)
    public func debugPrint(items: Any..., separator: String = " ", terminator: String = "\n") {

    }
    public func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {

    }
#endif

class AppDelegate: UIResponder, UIApplicationDelegate {
// App Delegate Code 

}


0

আমি এটি ব্যবহার করে শেষ করেছি:

#if DEBUG
func dLog(_ item: @autoclosure () -> Any, _ file: String = #file, _ function: String = #function, _ line: Int = #line) {
    print("\(Date()) [\((file as NSString).lastPathComponent):\(line) \(function)] \(item())")
}
#else
func dLog(_ item: @autoclosure () -> Any) {}
#endif

এটি বেশ কমপ্যাক্ট, কিছু দরকারী তথ্য মুদ্রণ করে (টাইমস্ট্যাম্প, সুইফ্ট ফাইলের নাম, কোড লাইন, ফাংশন নাম) এবং কমপক্ষে আমার পরীক্ষাগুলিতে আমি হেক্স এডিটরটিতে খোলার সময় অ্যাপ্লিকেশন বাইনারি ফাইলটিতে কোনও লগড স্ট্রিং খুঁজে পাইনি।


0

এমনকি সহজ: এই দাবিটি রিলিজ বিল্ডগুলি থেকে সরিয়ে ফেলা হয়েছে এবং কেবল সেখান থেকে মুদ্রণ কল করুন। এটি সমস্ত লগ কলগুলি সরিয়ে দেয় (হ্যাঁ, এমনকি লগ.ডায় কলগুলিও) কারণ তারা মুক্তির জন্য বিল্ডিংয়ের সময় খালি রয়েছে।

তবে আমি আরও শুনেছি যে রিলিজ বিল্ডগুলির জন্য প্রিন্টগুলি সরানো হয়েছে, তবে এটি লিখিতভাবে খুঁজে পেতে সক্ষম হয়নি। তাই আপাতত, আমি Logনীচে এই জাতীয় কিছু ব্যবহার করছি । ইমোজিগুলি (পঠনযোগ্যতার জন্য) এবং লগের বিষয়গুলি (ধারাবাহিকতার জন্য) সহ গিটহাবের কাছে আমার আরও মাংসল সংস্করণ রয়েছে:

https://github.com/Gatada/JBits/blob/master/Project/Uटिलity/Log.swift

public enum Log {

    /// A date formatter used to create the timestamp in the log.
    ///
    /// This formatter is only created if it is actually used, reducing the
    /// overhead to zero.
    static var formatter: DateFormatter?

    // MARK: - API

    /// Call to print message in debug area.
    ///
    /// Asserts are removed in release builds, which make
    /// the function body empty, which caused all calls to
    /// be removed as well.
    ///
    /// Result is zero overhead for release builds.
    public static func da(_ message: String) {
        assert(debugAreaPrint(message))
    }

    // MARK: - Helpers

    /// The function that actually does the printing. It returns `true` to
    /// prevent the assert from kicking in on debug builds.
    private static func debugAreaPrint(_ message: String) -> Bool {
        print("\(timestamp) - \(message)")
        return true
    }

    /// Creates a timestamp used as part of the temporary logging in the debug area.
    static private var timestamp: String {

        if formatter == nil {
            formatter = DateFormatter()
            formatter!.dateFormat = "HH:mm:ss.SSS"
        }

        let date = Date()
        return formatter!.string(from: date)
    }
}

কোডে:

Log.da("This is only handled in a debug build.")

শুধুমাত্র একটি ডিবাগ বিল্ড চালানোর সময় এক্সকোড ডিবাগ অঞ্চলে দেখা যায় :

13: 36: 15.047 - এটি কেবল একটি ডিবাগ বিল্ডে পরিচালনা করা হয়।


0

আমার প্রকল্পটি উদ্দেশ্য সি তে বিকাশ করা হয়েছিল, তবে গত বছর থেকেই আমি সুইফটে নতুন কোডটি মার্জ করা শুরু করেছি, সুতরাং নীচের সমাধানে সুইফটে আমার পক্ষে কাজ করেছে, আমি আমার সুইফট ধ্রুবক ফাইলটিতে সেই কোডটি যুক্ত করেছি:

func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
    #if DEBUG
    items.forEach {
        Swift.print($0, separator: separator, terminator: terminator)
    }
    #endif
}

0

এটি আমার পক্ষে কাজ করে (প্রকল্পে এটি একটি বিশ্বব্যাপী ফাংশন হিসাবে যুক্ত করুন)

func print(_ items: Any...) {
    #if DEBUG
        Swift.print(items[0])
    #endif
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.