সুইফট 2: কল নিক্ষেপ করতে পারে, তবে এটি 'চেষ্টা' দিয়ে চিহ্নিত করা হয়নি এবং ত্রুটিটি পরিচালনা করা হয় না


161

আমি এক্সকোড 7 বিটা ইনস্টল করার পরে এবং আমার সুইফট কোডটিকে সুইফ্ট 2 তে রূপান্তর করার পরে, কোডটি আমি খুঁজে পেতে পারি না তা নিয়ে আমি কিছু সমস্যা পেয়েছি। আমি জানি সুইফট 2 নতুন তাই আমি অনুসন্ধান করে খুঁজে বের করি কারণ এ সম্পর্কে কিছুই নেই, আমার একটি প্রশ্ন লেখা উচিত।

ত্রুটি এখানে:

কল নিক্ষেপ করতে পারে, তবে এটি 'চেষ্টা' দিয়ে চিহ্নিত করা হয়নি এবং ত্রুটিটি পরিচালনা করা হয় না

কোড:

func deleteAccountDetail(){
        let entityDescription = NSEntityDescription.entityForName("AccountDetail", inManagedObjectContext: Context!)
        let request = NSFetchRequest()
        request.entity = entityDescription

        //The Line Below is where i expect the error
        let fetchedEntities = self.Context!.executeFetchRequest(request) as! [AccountDetail]

        for entity in fetchedEntities {
        self.Context!.deleteObject(entity)
        }

        do {
            try self.Context!.save()
        } catch _ {
        }

    }

স্ন্যাপশট: এখানে চিত্র বর্ণনা লিখুন

উত্তর:


168

আপনি যেমনটি ইতিমধ্যে আপনার save()কলটির জন্য করছেন ঠিক তেমনি ত্রুটিটি ধরতে হবে এবং যেহেতু আপনি এখানে একাধিক ত্রুটি পরিচালনা করছেন, আপনি tryএককভাবে ডু-ক্যাচ ব্লকে ক্রমিকভাবে একাধিক কল করতে পারেন:

func deleteAccountDetail() {
    let entityDescription = NSEntityDescription.entityForName("AccountDetail", inManagedObjectContext: Context!)
    let request = NSFetchRequest()
    request.entity = entityDescription

    do {
        let fetchedEntities = try self.Context!.executeFetchRequest(request) as! [AccountDetail]

        for entity in fetchedEntities {
            self.Context!.deleteObject(entity)
        }

        try self.Context!.save()
    } catch {
        print(error)
    }
}

বা যেমন @ বেমস ৫৩ নীচের মন্তব্যে উল্লেখ করেছেন, যেখানে ত্রুটিটি ফেলেছিল তা ধরা না পড়াই প্রায়শই ভাল practice আপনি পদ্ধতি চিহ্ন হিসাবে পারেন throwsতারপর tryপদ্ধতি ডাকতে। উদাহরণ স্বরূপ:

func deleteAccountDetail() throws {
    let entityDescription = NSEntityDescription.entityForName("AccountDetail", inManagedObjectContext: Context!)
    let request = NSFetchRequest()

    request.entity = entityDescription

    let fetchedEntities = try Context.executeFetchRequest(request) as! [AccountDetail]

    for entity in fetchedEntities {
        self.Context!.deleteObject(entity)
    }

    try self.Context!.save()
}

এটি আমাকে এটি নির্ধারণ করতে সহায়তা করে, আপনাকে ধন্যবাদ।
ফরহাদ

5
আসলে এটি ব্যতিক্রম এখানে ধরা হবে যে প্রয়োজন হয় না। এটা ঠিক যোগ করার জন্য সম্ভব tryফাংশন কল করার শব্দ, এবং এই ফাংশন ডিক্লেয়ার করার মত func deleteAccountDetail() throw। অথবা যদি আপনি গ্যারান্টি দিয়ে থাকেন যে প্রদত্ত ইনপুটটির জন্য ফাংশনটি ছোঁড়াবে না, আপনি ব্যবহার করতে পারেন try!
bames53

4
আমি এটিকে নিতপিকের কাছে না এনেছি, তবে কারণ ব্যতিক্রম ভিত্তিক ত্রুটি পরিচালনার পক্ষে এটি বেশ গুরুত্বপূর্ণ যে ব্যতিক্রমগুলি বেশিরভাগ জায়গায় ব্যতিক্রম হয় না। এখানে তিন ধরণের জায়গা রয়েছে যেখানে ব্যতিক্রম ধরা উপযুক্ত। অন্য সমস্ত স্থানে কোডের ব্যতিক্রমগুলি স্পষ্টভাবে পরিচালনা করা উচিত নয় এবং deinit()পরিষ্কার করার জন্য অন্তর্নিহিত কলগুলির উপর নির্ভর করা উচিত (অর্থাত্, RAII), বা মাঝে মাঝে deferকিছু অ্যাডহক ক্লিনআপ করতে ব্যবহার করা উচিত। আরও তথ্যের জন্য ব্যাতিক্রম দেখুন
ডটকম

তবে আপনি কীভাবে এই ফাংশনটি চালাবেন? আমি যদি @ bames53 পথে যাই?
ফরহাদ

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

41

সুইফটে ঘোষিত throwsকোনও ফাংশন কল করার সময়, আপনাকে অবশ্যই সাথে tryবা এর সাথে ফাংশন কল সাইটটি বেনিফিট করতে হবে try!। উদাহরণস্বরূপ, একটি নিক্ষেপ ফাংশন দেওয়া:

func willOnlyThrowIfTrue(value: Bool) throws {
  if value { throw someError }
}

এই ফাংশনটি বলা যেতে পারে:

func foo(value: Bool) throws {
  try willOnlyThrowIfTrue(value)
}

এখানে আমরা কলটির সাথে এ্যানোটেট করি try, যা পাঠককে কল করে যে এই ফাংশনটি একটি ব্যতিক্রম ছুঁড়ে ফেলতে পারে, এবং নিম্নলিখিত কোডের কোনও লাইন কার্যকর করা হবে না। আমাদের সাথে throwsএই ফাংশনটিও বর্জন করতে হবে , কারণ এই ফাংশনটি একটি ব্যতিক্রম ছুঁড়ে ফেলতে পারে (অর্থাত্‍ যখন willOnlyThrowIfTrue()নিক্ষেপ করে, তখন fooস্বয়ংক্রিয়ভাবে ব্যতিক্রমটিকে উপরের দিকে পুনর্বিবেচনা করবে)।

আপনি যদি এমন কোনও ফাংশন কল করতে চান যা সম্ভবত নিক্ষেপ হিসাবে ঘোষণা করা হয়েছে তবে আপনি জানেন যা আপনার ক্ষেত্রে ফেলবে না কারণ আপনি এটি সঠিক ইনপুট দিচ্ছেন, আপনি ব্যবহার করতে পারেন try!

func bar() {
  try! willOnlyThrowIfTrue(false)
}

এইভাবে, যখন আপনি গ্যারান্টি দেন যে কোডটি নিক্ষেপ করবে না, তখন আপনাকে ব্যতিক্রম প্রচারগুলি অক্ষম করতে অতিরিক্ত বয়লারপ্লেট কোড লাগাতে হবে না।

try! রানটাইমে প্রয়োগ করা হয়: আপনি যদি ব্যবহার করেন try! এবং ফাংশনটি নিক্ষেপ শেষ করে না, তবে আপনার প্রোগ্রামের সম্পাদনা রানটাইম ত্রুটির সাথে সমাপ্ত হবে।

বেশিরভাগ ব্যতিক্রম হ্যান্ডলিং কোডটি উপরের মতো হওয়া উচিত: হয় ব্যতিক্রমগুলি ঘটে গেলে আপনি কেবল তার উপরের দিকে propagর্ধ্বমুখী প্রচার করেন বা আপনি এমন শর্ত সেট করেন যা অন্যথায় সম্ভাব্য ব্যতিক্রমগুলি বাতিল হয়ে যায়। আপনার কোডে অন্য সংস্থানসমূহের যে কোনও ক্লিন আপ হ'ল অবজেক্ট ধ্বংস (যেমন deinit()) বা কখনও কখনও deferএড কোডের মাধ্যমে হওয়া উচিত ।

func baz(value: Bool) throws {

  var filePath = NSBundle.mainBundle().pathForResource("theFile", ofType:"txt")
  var data = NSData(contentsOfFile:filePath)

  try willOnlyThrowIfTrue(value)

  // data and filePath automatically cleaned up, even when an exception occurs.
}

যদি কোনও কারণে আপনার ক্লিন আপ কোড রয়েছে যা চালানো দরকার তবে কোনও deinit()ফাংশনে নেই, আপনি ব্যবহার করতে পারেন defer

func qux(value: Bool) throws {
  defer {
    print("this code runs when the function exits, even when it exits by an exception")
  }

  try willOnlyThrowIfTrue(value)
}

ব্যতিক্রমগুলির সাথে সম্পর্কিত বেশিরভাগ কোডগুলিতে কেবল তারা কলারের কাছে wardর্ধ্বমুখী প্রচার করে, পথে deinit()বা মাধ্যমে ক্লিনআপ করেdefer । এটি কারণ বেশিরভাগ কোড ত্রুটিগুলি সহ কী করতে জানে না; এটি কী ভুল হয়েছে তা জানে, তবে ত্রুটি সম্পর্কে কী করা উচিত তা জানতে কিছু উচ্চ স্তরের কোড কী করার চেষ্টা করছে সে সম্পর্কে এর পর্যাপ্ত তথ্য নেই। এটি ব্যবহারকারীর কাছে একটি ডায়ালগ উপস্থাপন করা উপযুক্ত কিনা, বা এটি আবার চেষ্টা করা উচিত, বা অন্য কোনও কিছু উপযুক্ত কিনা তা জানা যায় না।

উচ্চ স্তরের কোডটি অবশ্য কোনও ত্রুটির ঘটনায় ঠিক কী করা উচিত তা জানা উচিত। সুতরাং ব্যতিক্রমগুলি নির্দিষ্ট ত্রুটিগুলি বুদবুদ করার অনুমতি দেয় যেখানে সেগুলি প্রথমে যেখানে পরিচালনা করা যায় সেখানে ঘটে occur

catchবিবৃতিগুলির মাধ্যমে ব্যতিক্রমগুলি পরিচালনা করা হয় ।

func quux(value: Bool) {
  do {
    try willOnlyThrowIfTrue(value)
  } catch {
    // handle error
  }
}

আপনার একাধিক ক্যাচ স্টেটমেন্ট থাকতে পারে, প্রতিটি একেক ধরণের ব্যতিক্রম ing

  do {
    try someFunctionThatThowsDifferentExceptions()
  } catch MyErrorType.errorA {
    // handle errorA
  } catch MyErrorType.errorB {
    // handle errorB
  } catch {
    // handle other errors
  }

ব্যতিক্রমসহ সর্বোত্তম কার্যাভ্যাস আরও বিশদের জন্য, দেখুন http://exceptionsafecode.com/ । এটি বিশেষত সি ++ এর লক্ষ্য, তবে সুইফট ব্যতিক্রম মডেলটি পরীক্ষা করার পরে, আমি বিশ্বাস করি যে বেসিকগুলি সুইফটেও প্রযোজ্য।

সুইফট সিনট্যাক্স এবং ত্রুটি পরিচালনার মডেল সম্পর্কে বিশদের জন্য দ্য সুইফ্ট প্রোগ্রামিং ল্যাঙ্গুয়েজ (সুইফট 2 প্রিরিলিজ) বইটি দেখুন ।


মূলত ধরলে কী ত্রুটি সামলানো যায়? বা ইনপুট ফাংশন
ফরহাদ

1
@ ব্রায়ানস আমি নিশ্চিত আপনি ঠিক কী জিজ্ঞাসা করছেন তা নিশ্চিত নই, বিশেষত একটি 'ইনপুট ফাংশন' সম্পর্কিত, তবে ব্যতিক্রমের প্রসঙ্গে 'ধরা' মূলত 'হ্যান্ডেল' এর প্রতিশব্দ। এর অর্থ এটি, ব্যতিক্রম ধরা এবং একটি ব্যতিক্রম পরিচালনা করা একই জিনিস, যতক্ষণ না প্রোগ্রামিং ভাষা সম্পর্কিত।
bames53

আমার এক ত্রুটি আছে আমি চুপ করে বুঝতে পারি না, আপনি কি আমাকে সাহায্য করতে পারেন? Invalid conversion from throwing function of type '() throws -> _' to non-throwing function type '(NSData?, NSURLResponse?, NSError?) -> Void'
ফরহাদ

@ ব্রায়ানস মনে হচ্ছে আপনি কোথাও একটি ভুল স্বাক্ষর সহ একটি ফাংশন ব্যবহার করছেন। এমন কিছু প্রত্যাশা করে যে কোনও ফাংশন দেওয়া হবে যা NSData?, NSURLResponse?, NSError?আর্গুমেন্ট হিসাবে গ্রহণ করে তবে আপনি এটিকে এমন একটি ফাংশন দিচ্ছেন যা কোনও যুক্তি না নেয়।
bames53

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