"মারাত্মক ত্রুটি: একটি ptionচ্ছিক মানটি মোড়কানোর সময় অপ্রত্যাশিতভাবে শূন্য" এর অর্থ কী?


415

আমার সুইফ্ট প্রোগ্রামটি ক্র্যাশ করছে EXC_BAD_INSTRUCTIONএবং নিম্নলিখিত অনুরূপ ত্রুটিগুলির মধ্যে একটি। এই ত্রুটিটির অর্থ কী এবং আমি কীভাবে এটি ঠিক করব?

মারাত্মক ত্রুটি: একটি ptionচ্ছিক মান মোড়ক দেওয়ার সময় অপ্রত্যাশিতভাবে শূন্যতা পাওয়া গেছে

অথবা

মারাত্মক ত্রুটি: একটি xpectedচ্ছিক মান সুস্পষ্টভাবে মোড়ক দেওয়ার সময় অপ্রত্যাশিতভাবে শূন্য হয়ে গেছে


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


8
@ রবার্ট কলম্বিয়া, এটি একটি সম্প্রদায়ের উইকিউইউ প্রশ্নোত্তর জুটির সাথে এই সমস্যার বিস্তৃত ডকুমেন্টেশন রয়েছে, আমি মনে করি না এমসিসিইর অভাবে এই প্রশ্নটি বন্ধ করা উচিত।
জাল

এর মতো পরিবর্তনশীল তৈরি করুন [var nameOfDaughter: স্ট্রিং? ] এবং এর মতো চলকটি ব্যবহার করুন [যদি _ = নামঅফডটারি {}] সেরা পন্থা।
আইওএস

উত্তর:


673

এই উত্তরটি হল সম্প্রদায় উইকি । আপনার যদি মনে হয় এটি আরও ভাল করা যায় তবে এটিকে সম্পাদনা করতে নির্দ্বিধায় !

পটভূমি: Oচ্ছিক কী?

সুইফটে, Optionalএকটি জেনেরিক টাইপ যা কোনও মান (যে কোনও ধরণের) থাকতে পারে, বা কোনও মানই রাখে না।

অন্যান্য অনেক প্রোগ্রামিং ভাষায়, একটি নির্দিষ্ট "সেন্ডিনেল" মান প্রায়শই একটি মানের অভাব বোঝাতে ব্যবহৃত হয় । উদ্দেশ্য-সিতে, উদাহরণস্বরূপ, nil( নাল পয়েন্টার ) কোনও বস্তুর অভাব নির্দেশ করে। তবে আদিম ধরণের সাথে কাজ করার সময় এটি আরও জটিল হয়ে -1ওঠে - কোনও পূর্ণসংখ্যার অনুপস্থিতি বা সম্ভবত INT_MIN, বা অন্য কোনও পূর্ণসংখ্যার ইঙ্গিত দেওয়ার জন্য ব্যবহার করা উচিত ? যদি কোনও নির্দিষ্ট মানটিকে "কোনও পূর্ণসংখ্যা না" বোঝার জন্য বেছে নেওয়া হয়, তার অর্থ এটি আর বৈধ মান হিসাবে বিবেচনা করা যাবে না ।

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

সুইফটে, যে কোনও প্রকারকে alচ্ছিক করা যেতে পারে । একটি alচ্ছিক মান মূল ধরণ বা বিশেষ মান থেকে যে কোনও মান নিতে পারে nil

বিকল্পগুলিতে ?প্রকারের প্রত্যয় দিয়ে সংজ্ঞায়িত করা হয় :

var anInt: Int = 42
var anOptionalInt: Int? = 42
var anotherOptionalInt: Int?    // `nil` is the default when no value is provided

একটি alচ্ছিক মধ্যে একটি মান অভাব দ্বারা চিহ্নিত করা হয় nil:

anOptionalInt = nil

(দ্রষ্টব্য যে এটি ওজেক্টিভ-সি এর nilমতো নয় nilOb অবজেক্টিভ-সি-তে nilবৈধ অবজেক্ট পয়েন্টারের অনুপস্থিতি ; সুইফ্টে বিকল্পগুলি বস্তু / রেফারেন্সের ধরণের মধ্যে সীমাবদ্ধ নয় Has alচ্ছিক হাসকেলের সম্ভবত একই আচরণ করে ))


আমি কেন " মারাত্মক ত্রুটি: অপশনালিক মানটি আবরণ করার সময় অপ্রত্যাশিতভাবে পাওয়া গেলাম "?

Anচ্ছিকের মানটি অ্যাক্সেস করতে (যদি এর কোনও একটি থাকে), আপনাকে এটি মোড়ানো দরকার । একটি alচ্ছিক মান নিরাপদে বা জোর করে মোড়ানো যায়। যদি আপনি একটি forceচ্ছিককে জোর-আন-মোড়ক করেন এবং এর কোনও মান না থাকে তবে আপনার প্রোগ্রামটি উপরের বার্তার সাথে ক্রাশ হবে।

কোডের লাইন হাইলাইট করে এক্সকোড আপনাকে ক্র্যাশ দেখায়। এই লাইনে সমস্যা দেখা দেয়।

ক্র্যাশ লাইন

এই ক্র্যাশ দুটি ভিন্ন ধরণের জোর-আন-মোড়ের সাথে ঘটতে পারে:

1. সুস্পষ্ট বাহিনী মোড়ানো

এটি !অপারেটরের সাথে একটি onচ্ছিকভাবে করা হয়। উদাহরণ স্বরূপ:

let anOptionalString: String?
print(anOptionalString!) // <- CRASH

মারাত্মক ত্রুটি: একটি ptionচ্ছিক মান মোড়ক দেওয়ার সময় অপ্রত্যাশিতভাবে শূন্যতা পাওয়া গেছে

হিসাবে anOptionalStringহয় nilএখানে, আপনি লাইন যেখানে আপনি এটি মোড়ক খোলা বাধ্য উপর একটি ক্র্যাশ পাবেন।

2. সুস্পষ্টভাবে মোড়ানো বিকল্পগুলি

এগুলি টাইপের পরে !পরিবর্তে একটি দ্বারা সংজ্ঞায়িত করা হয় ?

var optionalDouble: Double!   // this value is implicitly unwrapped wherever it's used

এই বিকল্পগুলির একটি মান রয়েছে বলে ধরে নেওয়া হয়। অতএব আপনি যখনই কোনও অন্তর্নিহিত wচ্ছিক accessচ্ছিক অ্যাক্সেস করবেন তখন তা স্বয়ংক্রিয়ভাবে আপনার জন্য মোড়কে মোড়ানো হবে। এতে যদি কোনও মান না থাকে তবে এটি ক্রাশ হবে।

print(optionalDouble) // <- CRASH

মারাত্মক ত্রুটি: একটি xpectedচ্ছিক মান সুস্পষ্টভাবে মোড়ক দেওয়ার সময় অপ্রত্যাশিতভাবে শূন্য হয়ে গেছে

কোন ভেরিয়েবল ক্রাশের কারণ হয়ে ওঠার জন্য, সংজ্ঞাটি দেখানোর জন্য ক্লিক করতে গিয়ে আপনি ধরে রাখতে পারেন , যেখানে আপনি alচ্ছিক প্রকারটি খুঁজে পেতে পারেন।

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


কখন আমাকে anচ্ছিক আন-র‌্যাপ জোর করা উচিত?

সুস্পষ্ট বাহিনী মোড়ানো

একটি সাধারণ নিয়ম হিসাবে, আপনাকে !অপারেটরের সাথে কোনও বিকল্প wচ্ছিকভাবে মোড়ানোর বিষয়টি স্পষ্টভাবে জোর করা উচিত নয় । এমন কিছু ক্ষেত্রে থাকতে পারে যেখানে !ব্যবহারটি গ্রহণযোগ্য হয় - তবে আপনি কেবলমাত্র এটি ব্যবহার করা উচিত যদি আপনি 100% নিশ্চিত হন যে alচ্ছিকর কোনও মান রয়েছে।

সেখানে থাকাকালীন পারে একটি উপলক্ষ্য যেখানে আপনি বল unwrapping ব্যবহার করতে পারেন, যেমন আপনি একটি জানি হতে সত্য যে একটি ঐচ্ছিক একটি মান ধারণ করে - সেখানে একটি নয় একক জায়গা যেখানে আপনি যা করতে পারেন না নিরাপদে মোড়ক খোলা যে ঐচ্ছিক পরিবর্তে।

সুস্পষ্টভাবে মোড়ানো বিকল্পগুলি ption

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

আপনার কেবলমাত্র শেষ অবলম্বন হিসাবে অন্তর্নিহিত বিকল্পগুলি ব্যবহার করা উচিত । যদি আপনি একটি অলস ভেরিয়েবল ব্যবহার করতে পারেন , বা কোনও ভেরিয়েবলের জন্য একটি ডিফল্ট মান সরবরাহ করতে পারেন - তবে আপনাকে স্পষ্টতভাবে মোড়কযুক্ত raচ্ছিক ব্যবহারের পরিবর্তে এটি করা উচিত।

তবে, হয় কয়েক পরিস্থিতিতে যেখানে পরোক্ষভাবে মোড়ানো optionals উপকারী , আর এখনও আপনার নিরাপদে তাদের unwrapping নীচে তালিকাভুক্ত হিসেবে বিভিন্ন উপায়ে ব্যবহার করতে পারবেন - কিন্তু আপনি উচিত সবসময় কারণে সতর্কতার সাথে তাদের ব্যবহার।


আমি কীভাবে বিকল্পগুলি মোকাবেলা করতে পারি?

Optionচ্ছিক কোনও মান রয়েছে কিনা তা যাচাই করার সহজ উপায়টি এর সাথে তুলনা করা nil

if anOptionalInt != nil {
    print("Contains a value!")
} else {
    print("Doesn’t contain a value.")
}

যাইহোক, বিকল্পগুলির সাথে কাজ করার সময় 99.9% সময়, আপনি আসলে এতে থাকা মানটি অ্যাক্সেস করতে চান, যদি এতে কোনও একটি থাকে contains এটি করতে, আপনি Oচ্ছিক বাঁধাই ব্যবহার করতে পারেন ।

Ptionচ্ছিক বাঁধাই

Ptionচ্ছিক বাঁধাই আপনাকে checkচ্ছিক কোনও মান রয়েছে কিনা তা যাচাই করতে দেয় - এবং আপনাকে মোড়কযুক্ত মানটিকে একটি নতুন ভেরিয়েবল বা ধ্রুবককে বরাদ্দ করতে দেয়। এটি সিনট্যাক্স ব্যবহার করে if let x = anOptional {...}বা if var x = anOptional {...}নির্ভর করে যদি আপনি এটি বাঁধার পরে নতুন ভেরিয়েবলের মান পরিবর্তন করতে চান।

উদাহরণ স্বরূপ:

if let number = anOptionalInt {
    print("Contains a value! It is \(number)!")
} else {
    print("Doesn’t contain a number")
}

এটি যা করে তা প্রথমে পরীক্ষা করে দেখুন যে alচ্ছিকটিতে একটি মান রয়েছে। যদি এটি হয় , তবে 'মোড়কযুক্ত' মানটি একটি নতুন ভেরিয়েবল ( number) - এ নির্ধারিত হয়েছে - যা আপনি নির্দ্বিধায় ব্যবহার করতে পারেন যেমন এটি অ-alচ্ছিক। Alচ্ছিকতে যদি কোনও মান থাকে না , তবে অন্য অনুচ্ছেদটি আহ্বান করা হবে, যেমনটি আপনি আশা করেছিলেন।

Alচ্ছিক বাঁধাই সম্পর্কে ঝরঝরে কী, আপনি একই সময়ে একাধিক বিকল্প আনারপেট করতে পারেন। আপনি কেবল কমা দিয়ে বিবৃতিগুলি পৃথক করতে পারেন। সমস্ত বিকল্প অপরিবর্তিত থাকলে বিবৃতিটি সফল হবে।

var anOptionalInt : Int?
var anOptionalString : String?

if let number = anOptionalInt, let text = anOptionalString {
    print("anOptionalInt contains a value: \(number). And so does anOptionalString, it’s: \(text)")
} else {
    print("One or more of the optionals don’t contain a value")
}

আরেকটি ঝরঝরে কৌশলটি হ'ল আপনি এটি মুছে ফেলার পরে মানটির একটি নির্দিষ্ট শর্ত পরীক্ষা করতে কমা ব্যবহার করতে পারেন।

if let number = anOptionalInt, number > 0 {
    print("anOptionalInt contains a value: \(number), and it’s greater than zero!")
}

যদি একটি বিবৃতিতে alচ্ছিক বাঁধাই ব্যবহার করে তবেই কেবল ধরা পড়বে যে আপনি কেবলমাত্র বিবৃতিটির ক্ষেত্রের মধ্যে থেকে মোড়কানো মানটি অ্যাক্সেস করতে পারবেন। আপনার যদি বিবৃতিটির সুযোগের বাইরে থেকে মানটির অ্যাক্সেসের প্রয়োজন হয় তবে আপনি গার্ড স্টেটমেন্ট ব্যবহার করতে পারেন ।

একজন গার্ড বিবৃতি আপনি সাফল্যের জন্য একটি শর্ত সংজ্ঞায়িত করতে পারবেন - এবং যদি সেই শর্ত পূরণ করা হয় বর্তমান সুযোগ শুধুমাত্র নির্বাহ চলতে থাকবে। এগুলি সিনট্যাক্স দিয়ে সংজ্ঞায়িত করা হয় guard condition else {...}

সুতরাং, anচ্ছিক বাঁধাইয়ের সাথে এগুলি ব্যবহার করতে, আপনি এটি করতে পারেন:

guard let number = anOptionalInt else {
    return
}

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

যদি anOptionalIntকোনও মান থাকে, তবে এটি মোড়ানো হবে এবং নতুন numberধ্রুবককে নির্ধারিত হবে । গার্ডের পরে কোডটি কার্যকর করা চালিয়ে যাবে। যদি এটিতে কোনও মান না থাকে - গার্ডটি বন্ধনীগুলির মধ্যে কোডটি কার্যকর করে, যা নিয়ন্ত্রণের স্থানান্তর করতে পরিচালিত করে, যাতে তত্ক্ষণাত কোড কার্যকর করা হবে না।

প্রহরী বিবৃতি সম্পর্কে আসল ঝরঝরে জিনিস হ'ল মোড়কযুক্ত মানটি এখন বিবৃতি অনুসরণকারী কোডে ব্যবহারের জন্য উপলব্ধ (যেমন আমরা জানি যে ভবিষ্যতের কোডটি কেবলমাত্র theচ্ছিকের মান থাকলে কার্যকর করতে পারে)। বিবৃতিগুলি যদি একাধিক বাসা বাঁধে তৈরি করা হয় 'ডুমের পিরামিডস' নির্মূল করার জন্য এটি দুর্দান্ত ।

উদাহরণ স্বরূপ:

guard let number = anOptionalInt else {
    return
}

print("anOptionalInt contains a value, and it’s: \(number)!")

গার্ডগুলি একই ঝরঝরে কৌশলগুলিকে সমর্থন করে যা if স্টেটমেন্টটি সমর্থন করে যেমন একই সময়ে একাধিক বিকল্পকে মোড়ানো এবং whereধারাটি ব্যবহার করে ।

আপনি যদি কোনও বা গার্ডের বিবৃতি ব্যবহার করেন তা পুরোপুরি নির্ভর করে যে কোনও ভবিষ্যতের কোডের একটি মান থাকতে alচ্ছিক প্রয়োজন কিনা on

নিল কোলেসিং অপারেটর

নীল কোয়ালেসিং অপারেটর একটি ছিমছাম সাধারণভাবে সংক্ষেপে সংস্করণ তিন শর্তসাপেক্ষ অপারেটর , প্রাথমিকভাবে অ optionals করার optionals রূপান্তর করতে পরিকল্পিত। এটির বাক্য গঠন রয়েছে a ?? b, যেখানে aএকটি optionচ্ছিক প্রকার এবং bএটি একই ধরণের a(যদিও সাধারণত অ-optionচ্ছিক)।

এটি মূলত আপনাকে বলতে দেয় "যদি aকোনও মান থাকে তবে এটি মোড়ক করুন। যদি তা না হয় তবে bপরিবর্তে ফিরে আসুন। উদাহরণস্বরূপ, আপনি এটি ব্যবহার করতে পারেন:

let number = anOptionalInt ?? 0

এটি ধরণের numberধ্রুবককে সংজ্ঞায়িত করবে Int, এর মধ্যে মান রয়েছে anOptionalInt, যদি এটিতে কোনও মান থাকে, বা 0অন্যথায়।

এটি কেবল শর্টহ্যান্ডের জন্য:

let number = anOptionalInt != nil ? anOptionalInt! : 0

.চ্ছিক চেইনিং

কোনও পদ্ধতিতে কল করতে বা propertyচ্ছিক কোনও সম্পত্তি অ্যাক্সেস করতে আপনি alচ্ছিক চেইনিং ব্যবহার করতে পারেন । এটি ভেরিয়েবলের নামটি ?ব্যবহার করার সাথে সাথে প্রত্যাহার করেই করা হয় ।

উদাহরণস্বরূপ, বলুন যে আমাদের একটি ভেরিয়েবল আছে, একটি fooofচ্ছিক Fooউদাহরণ টাইপ করুন ।

var foo : Foo?

যদি আমরা কোনও পদ্ধতিতে কল করতে চেয়েছিলাম fooযে কোনও কিছুই ফিরে আসে না, আমরা কেবল এটি করতে পারি:

foo?.doSomethingInteresting()

যদি fooকোনও মান থাকে, তবে এই পদ্ধতিটি এতে কল করা হবে। যদি এটি না ঘটে তবে খারাপ কিছু ঘটবে না - কোডটি কেবল কার্যকর করা চালিয়ে যাবে।

( nilউদ্দেশ্য-সি তে বার্তা প্রেরণের অনুরূপ আচরণ )

এই কারণে বৈশিষ্ট্য পাশাপাশি কল পদ্ধতি সেট করতেও এটি ব্যবহার করা যেতে পারে। উদাহরণ স্বরূপ:

foo?.bar = Bar()

আবার, কিছুই খারাপ এখানে ঘটবে যদি fooহয় nil। আপনার কোডটি কার্যকরভাবে চালানো চালিয়ে যাবে।

Neচ্ছিক শৃঙ্খলা যা আপনাকে করতে দেয় এমন আরেকটি ঝরঝরে কৌশলটি কোনও সম্পত্তি সেট করা বা কোনও পদ্ধতি কল করা সফল হয়েছিল কিনা তা যাচাই করে দেখানো হয়। আপনি রিটার্ন মানটি তুলনা করে এটি করতে পারেন nil

(এটি কারণ এমন কোনও পদ্ধতির Void?পরিবর্তে anythingচ্ছিক মান ফিরে আসবে Voidযা কোনও কিছুই ফেরত না)

উদাহরণ স্বরূপ:

if (foo?.bar = Bar()) != nil {
    print("bar was set successfully")
} else {
    print("bar wasn’t set successfully")
}

যাইহোক, বৈশিষ্ট্যগুলি অ্যাক্সেস করার চেষ্টা করার সময় বা মানগুলি ফেরত দেওয়ার পদ্ধতিগুলিতে কিছুটা আরও জটিল হয়ে ওঠে। যেহেতু fooisচ্ছিক, এখান থেকে ফিরে আসা যে কোনও কিছুই alচ্ছিকও হবে। এটির সাথে মোকাবিলা করার জন্য, আপনি উপরের যে কোনও একটি পদ্ধতি ব্যবহার করে ফিরে আসা বিকল্পগুলি আন-মোড়ক করতে পারেন - অথবা fooপদ্ধতিগুলি অ্যাক্সেস করার আগে বা মানগুলি ফেরত দেওয়ার পদ্ধতিগুলিতে কল করার আগে নিজেকে মোড়ক থেকে মুক্ত করতে পারেন।

এছাড়াও, নামটি যেমন বোঝায়, আপনি এই বিবৃতিগুলি একসাথে 'চেইন' করতে পারেন। এর অর্থ হ'ল যদি fooএকটি optionচ্ছিক সম্পত্তি থাকে baz, যার একটি সম্পত্তি থাকে qux- তবে আপনি নিম্নলিখিতটি লিখতে পারেন:

let optionalQux = foo?.baz?.qux

আবার, কারণ fooএবং bazalচ্ছিক, এ থেকে প্রাপ্ত মানটি quxসর্বদা একটি alচ্ছিক হবে তা নির্বিশেষে quxনিজেই optionচ্ছিক।

map এবং flatMap

বিকল্পগুলির সাথে একটি প্রায়শই নিহিত বৈশিষ্ট্য হ'ল mapএবং flatMapকার্যগুলি ব্যবহার করার ক্ষমতা । এগুলি আপনাকে alচ্ছিক ভেরিয়েবলগুলিতে অ-alচ্ছিক রূপান্তর প্রয়োগ করতে দেয়। Anচ্ছিকের যদি কোনও মান থাকে তবে আপনি এটিতে প্রদত্ত রূপান্তরটি প্রয়োগ করতে পারেন। যদি এর কোনও মান না থাকে তবে তা থেকে যায় nil

উদাহরণস্বরূপ, ধরা যাক আপনার একটি alচ্ছিক স্ট্রিং রয়েছে:

let anOptionalString:String?

এতে mapফাংশনটি প্রয়োগ করে - আমরা stringByAppendingStringফাংশনটি এটি অন্য স্ট্রিংয়ের সাথে যুক্ত করতে ব্যবহার করতে পারি ।

যেহেতু stringByAppendingStringএকটি অ-alচ্ছিক স্ট্রিং আর্গুমেন্ট লাগে তাই আমরা আমাদের alচ্ছিক স্ট্রিংটি সরাসরি ইনপুট করতে পারি না। তবে, ব্যবহার করে map, আমরা কোনও মান stringByAppendingStringথাকলে ব্যবহার করার অনুমতি ব্যবহার করতে পারি anOptionalString

উদাহরণ স্বরূপ:

var anOptionalString:String? = "bar"

anOptionalString = anOptionalString.map {unwrappedString in
    return "foo".stringByAppendingString(unwrappedString)
}

print(anOptionalString) // Optional("foobar")

তবে, anOptionalStringমান না থাকলে, mapফিরে আসবে nil। উদাহরণ স্বরূপ:

var anOptionalString:String?

anOptionalString = anOptionalString.map {unwrappedString in
    return "foo".stringByAppendingString(unwrappedString)
}

print(anOptionalString) // nil

flatMapঅনুরূপভাবে কাজ করে map, বাদে এটি আপনাকে ক্লোজর বডি থেকে অন্য optionচ্ছিক ফিরে আসতে দেয় । এর অর্থ আপনি একটি প্রক্রিয়াতে একটি alচ্ছিক ইনপুট করতে পারেন যার জন্য একটি অ-alচ্ছিক ইনপুট প্রয়োজন, তবে anচ্ছিক নিজেই আউটপুট করতে পারেন।

try!

ডু-ট্রাই-ক্যাচের সাথে সুইফ্টের ত্রুটি হ্যান্ডলিং সিস্টেমটি নিরাপদে ব্যবহার করা যেতে পারে :

do {
    let result = try someThrowingFunc() 
} catch {
    print(error)
}

যদি someThrowingFunc()কোনও ত্রুটি নিক্ষেপ করে, ত্রুটিটি নিরাপদে catchব্লকে ধরা পড়বে ।

errorআপনি catchব্লকে যে ধ্রুবকটি দেখছেন তা আমাদের দ্বারা ঘোষণা করা হয়নি - এটি স্বয়ংক্রিয়ভাবে উত্পন্ন হয় catch

আপনি errorনিজেই ঘোষণা করতে পারেন , এটি একটি দরকারী বিন্যাসে কাস্ট করতে সক্ষম হওয়ার সুবিধা রয়েছে, উদাহরণস্বরূপ:

do {
    let result = try someThrowingFunc()    
} catch let error as NSError {
    print(error.debugDescription)
}

tryএই পদ্ধতি ব্যবহার করে নিক্ষেপ ফাংশন থেকে আসা ত্রুটিগুলি চেষ্টা করার, ধরা ও পরিচালনা করার উপযুক্ত উপায়।

এর রয়েছে try?যা ত্রুটি শোষণ:

if let result = try? someThrowingFunc() {
    // cool
} else {
    // handle the failure, but there's no error information available
}

তবে সুইফ্টের ত্রুটি পরিচালনা ব্যবস্থাও এর সাথে "জোর করে চেষ্টা" করার একটি উপায় সরবরাহ করে try!:

let result = try! someThrowingFunc()

এই পোস্টে ব্যাখ্যা করা ধারণাগুলি এখানেও প্রয়োগ হয়: যদি কোনও ত্রুটি নিক্ষেপ করা হয় তবে অ্যাপ্লিকেশনটি ক্রাশ হবে।

আপনি কেবল তখনই ব্যবহার try!করতে পারেন যদি আপনি প্রমাণ করতে পারেন যে এর ফলাফলটি আপনার প্রসঙ্গে কখনও ব্যর্থ হবে না - এবং এটি খুব বিরল।

বেশিরভাগ সময় আপনি সম্পূর্ণ কর-চেষ্টা-ক্যাচ সিস্টেমটি ব্যবহার করবেন - এবং theচ্ছিক একটি, try?বিরল ক্ষেত্রে যেখানে ত্রুটি পরিচালনা করা গুরুত্বপূর্ণ নয়।


সম্পদ


87
ব্যক্তিগতভাবে, আমি এই সমস্ত লেখার প্রচেষ্টা চালিয়ে যাওয়ার জন্য আপনাকে ধন্যবাদ জানাতে চাই। আমি মনে করি এটি অবশ্যই সুইফট ব্যবহার করে প্রথমত এবং বিশেষজ্ঞদের পক্ষে সহায়ক হবে।
প্রণব ওয়াদওয়া

15
আপনি এটি সহায়ক বলে আমি খুশি। এই উত্তরটি সম্প্রদায় উইকি, তাই এটি অনেক লোকের মধ্যে একটি সহযোগিতা (7, এখনও অবধি)!
jtbandes

1
এই ত্রুটিটি আমার ক্ষেত্রে মাঝে মাঝে রয়েছে। কোন পরামর্শ? মধ্যে Code stackoverflow.com/questions/50933681/...
py_ios_dev

1
সম্ভবত এটি compactMap()পরিবর্তে পরিবর্তে এই উত্তরটি আপডেট করার সময় flatMap()
নিকোলাস মিয়ারি

সুতরাং আমি অনুমান করি যে সবচেয়ে ভাল এবং সংক্ষিপ্ত সমাধানটি "নীল কোলেসিংস অপারেটর", তাই না?
মেহেদিগ্রিচ

65

টিএল; ডিআর উত্তর

সঙ্গে খুব কয়েক ব্যতিক্রম এই নিয়ম সুবর্ণ হল:

এর ব্যবহার এড়িয়ে চলুন !

ভেরিয়েবল ?alচ্ছিক ( ) ঘোষণা করুন , সুস্পষ্টভাবে মোড়ক না করা বিকল্পগুলি (আইইউ) ( !)

অন্য কথায়, বরং ব্যবহার করুন:
var nameOfDaughter: String?

পরিবর্তে:
var nameOfDaughter: String!

if letবা ব্যবহার করে alচ্ছিক পরিবর্তনশীল মোড়ানোguard let

হয় এর মতো মোড়ক মোড়ক উন্মুক্ত করুন:

if let nameOfDaughter = nameOfDaughter {
    print("My daughters name is: \(nameOfDaughter)")
}

বা এই মত:

guard let nameOfDaughter = nameOfDaughter else { return }
print("My daughters name is: \(nameOfDaughter)")

এই উত্তরটি সংক্ষিপ্ত হওয়ার উদ্দেশ্যে করা হয়েছিল, সম্পূর্ণ বোধগম্যতার জন্য গ্রহণযোগ্য উত্তর পড়ুন


সম্পদ


40

এই প্রশ্নটি তাই সমস্ত সময় আসে । এটি নতুন প্রথম সুইট বিকাশকারীদের সাথে লড়াই করা প্রথম জিনিসগুলির মধ্যে একটি।

পটভূমি:

একটি মান থাকতে পারে বা না পারে এমন মানগুলিকে মোকাবেলায় সুইফট "বিকল্পগুলি" ধারণাটি ব্যবহার করে। সি এর মতো অন্যান্য ভাষায়, আপনি কোনও ভেরিয়েবলের মধ্যে 0 এর মান সঞ্চয় করতে পারেন যাতে এটির কোনও মূল্য নেই indicate তবে, 0 যদি একটি বৈধ মান হয়? তারপরে আপনি -1 ব্যবহার করতে পারেন। -1 যদি একটি কার্যকর মান হয়? ইত্যাদি।

সুইফ্ট বিকল্পগুলি আপনাকে বৈধ মান, বা কোনও মান না রাখতে কোনও ধরণের ভেরিয়েবল সেট আপ করতে দেয়।

আপনি যখন ভেরিয়েবলকে বোঝাতে (টাইপ এক্স, বা কোনও মান নেই) প্রকারের পরে একটি প্রশ্ন চিহ্ন রেখেছিলেন।

একটি alচ্ছিক আসলে একটি ধারক যা কোনও প্রদত্ত প্রকারের ভেরিয়েবল থাকে বা কিছুই কিছুই থাকে না।

অভ্যন্তরের মানটি আনতে একটি alচ্ছিককে "মোড়ানো" হওয়া দরকার।

দ্য "!" অপারেটর একটি "ফোর্স আনআরপ" অপারেটর। এটি বলে "" আমাকে বিশ্বাস করুন। আমি জানি আমি কী করছি I আমি গ্যারান্টি দিচ্ছি যে এই কোডটি চললে চলকটিতে শূন্য থাকবে না। " আপনি যদি ভুল হয়ে থাকেন তবে আপনার ক্রাশ হবে।

যতক্ষণ না আপনি সত্যিই কি জানি তুমি কি করছ, এড়ানো "!" অপারেটর অপসারণ বাধ্য করুন। এটি সম্ভবত সুইফ্ট প্রোগ্রামার শুরু করার জন্য ক্র্যাশের বৃহত্তম উত্স।

বিকল্পগুলির সাথে কীভাবে আচরণ করবেন:

নিরাপদ বিকল্পগুলির সাথে মোকাবিলা করার প্রচুর অন্যান্য উপায় রয়েছে। এখানে কিছু (সম্পূর্ণ তালিকা নয়)

আপনি "optionচ্ছিক বাঁধাই" বা "যদি বলুন" বলতে পারেন যদি এই alচ্ছিকটিতে একটি মান থাকে তবে সেই মানটিকে একটি নতুন, অ-optionচ্ছিক ভেরিয়েবলে সংরক্ষণ করুন theচ্ছিক কোনও মান না রাখলে, যদি বিবৃতিটির মূল অংশটি এড়িয়ে যান "।

এখানে আমাদের fooal চ্ছিক সাথে alচ্ছিক বাঁধাইয়ের একটি উদাহরণ রয়েছে :

if let newFoo = foo //If let is called optional binding. {
  print("foo is not nil")
} else {
  print("foo is nil")
}

নোট করুন যে আপনি যখন ভেরিয়েবলটি সংজ্ঞায়িত করেন তখন যখন আপনি alচ্ছিক বিডিং ব্যবহার করেন কেবল তখনই স্টেটমেন্টের শৃঙ্খলে থাকে (কেবল "সুযোগ" থাকে)।

পর্যায়ক্রমে, আপনি একটি গার্ড স্টেটমেন্ট ব্যবহার করতে পারেন, যা ভেরিয়েবলটি শূন্য থাকলে আপনার ফাংশন থেকে বেরিয়ে আসতে দেয়:

func aFunc(foo: Int?) {
  guard let newFoo = input else { return }
  //For the rest of the function newFoo is a non-optional var
}

গার্ডের বিবৃতিগুলি সুইফট ২-এ যুক্ত করা হয়েছে গার্ড আপনাকে আপনার কোডের মাধ্যমে "সোনালি পথ" সংরক্ষণ করতে দেয় এবং নেস্টেড আইএফএসের ক্রমবর্ধমান স্তরগুলি এড়াতে দেয় যা কখনও কখনও "যদি লেট করুন" alচ্ছিক বাঁধাইয়ের ফলে আসে।

"নিল কোয়েলসিং অপারেটর" নামে একটি নির্মাণও রয়েছে। এটি "alচ্ছিক_ভার ?? প্রতিস্থাপন_ভাল" রূপটি নেয়। এটি typeচ্ছিক মধ্যে থাকা ডেটার মতো একই ধরণের একটি অ-alচ্ছিক পরিবর্তনশীল দেয়। Theচ্ছিকতে যদি শূন্য থাকে তবে এটি "??" এর পরে অভিব্যক্তির মান প্রদান করে প্রতীক।

সুতরাং আপনি এই জাতীয় কোড ব্যবহার করতে পারেন:

let newFoo = foo ?? "nil" // "??" is the nil coalescing operator
print("foo = \(newFoo)")

আপনি চেষ্টা / ধরা বা গার্ড ত্রুটি পরিচালনার ব্যবহার করতে পারেন, তবে সাধারণত উপরের অন্যান্য কৌশলগুলির মধ্যে একটি ক্লিনার er

সম্পাদনা করুন:

অপশনালগুলির সাথে আরেকটি, সূক্ষ্মভাবে আরও কিছু সূক্ষ্ম গ্যাচা হ'ল "অন্তর্নিহিত অপরিবর্তিত বিকল্পসমূহ। আমরা যখন foo ঘোষণা করি তখন আমরা বলতে পারি:

var foo: String!

সেক্ষেত্রে ফু এখনও একটি alচ্ছিক, তবে আপনাকে এটি রেফারেন্স করার জন্য এটি মোছার দরকার নেই। এর অর্থ আপনি যখনই foo রেফারেন্স দেওয়ার চেষ্টা করবেন, এটি শুন্য না হলে আপনি ক্র্যাশ হয়ে যাবেন।

সুতরাং এই কোড:

var foo: String!


let upperFoo = foo.capitalizedString

Foo এর মূলধন স্ট্রিং সম্পত্তির প্রসঙ্গে ক্রাশ হবে যদিও আমরা ফো-কে জোর-মোড়ক না ছুঁড়ে দেখছি। প্রিন্টটি দেখতে বেশ ভাল লাগছে, তবে তা নয়।

সুতরাং আপনি স্পষ্টভাবে মোড়কযুক্ত বিকল্পগুলি সম্পর্কে সত্যই সতর্ক হতে চান। (এবং আপনার এমনকি বিকল্পগুলির সম্পর্কে দৃ understanding় ধারণা না পাওয়া পর্যন্ত এগুলি পুরোপুরি এড়িয়ে চলুন))

নীচের লাইন: আপনি যখন প্রথম সুইফট শিখছেন তখন "!" চরিত্র ভাষার অংশ নয়। এটি আপনাকে সমস্যায় ফেলতে পারে।


7
এটিকে একটি সর্বজনীন উইকি হিসাবে বিবেচনা করা উচিত।
ভ্যাকোয়ামা

3
আপনার উত্তরটি সম্পাদনা করুন এবং ডানদিকে সম্পাদনা বাক্সের নীচে একটি সম্প্রদায় উইকি চেকবক্স রয়েছে। উত্তরের জন্য আপনি আর খ্যাতি পাবেন না, তবে আমি জানি এটি যাইহোক নির্দোষ প্রতিবেদক নয়।
ভ্যাকওমা

6
এই প্রশ্নটি সাইটে এক মিলিয়ন বার জিজ্ঞাসা করা হয়েছে, যদি আমি যদি প্রশ্নের উত্তরটিকে স্বতঃস্ফূর্ত উত্তর হিসাবে একটি স্ব-উত্তরযুক্ত প্রশ্ন পোস্ট করার জন্য সময় নিচ্ছিলাম তবে আমি আশা করি যে উত্তরটি এর চেয়ে অনেক বেশি পূর্ণ। guardদফা সম্পর্কে কিছুই নেই । এর ব্যবহার সম্পর্কে কিছুই নেই if varযা নির্মাণের মতোই বৈধ if let। বাঁধাইয়ের whereকথা বলার সময় আমি যে দফাগুলি মনে করি তা উল্লেখ করার মতো কিছুই নেই if let(এটি অনেক ক্ষেত্রে বাসা বাঁধার পুরো স্তরটি সরিয়ে দেয়)। Alচ্ছিক চেইন সম্পর্কে কিছুই নেই।
nhgrif

6
এবং যখন আপনি স্পষ্টতভাবে মোড়কযুক্ত বিকল্পগুলি উল্লেখ করেন, আপনি এমনকি উল্লেখও করেন না যে আপনি পরিষ্কারভাবে আবদ্ধভাবে আবদ্ধ বিকল্পগুলি মোছার জন্য উপরে উল্লিখিত optionচ্ছিক সকল কৌশল ব্যবহার করতে পারেন। আমরা একই ধারাটিতে মোড়ক দেওয়া একাধিক বিকল্পগুলিও কভার করি না।
nhgrif

1
@ এনজিগ্রিফ, আমি বলেছিলাম "আপনি চেষ্টা / ধরা বা ত্রুটি পরিচালনা রক্ষা করতেও ব্যবহার করতে পারেন, তবে সাধারণত উপরের অন্যান্য কৌশলগুলির মধ্যে একটি ক্লিনার clean" আপনার অবশ্যই কিছু ভাল পয়েন্ট আছে। এটি মোটামুটি বড় বিষয়। আপনার নিজের উত্তরের অবদানের বিষয়ে কীভাবে আমি যে মন্তব্যগুলি স্নিপিংয়ের পরিবর্তে করিনি সেগুলি কভার করে? এইভাবে প্রশ্ন এবং এর উত্তরগুলি সাইটের আরও ভাল সম্পদে পরিণত হয়।
ডানকান সি

13

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

Alচ্ছিক চলক ঘোষণার আরেকটি উপায় হ'ল

var i : Optional<Int>

এবং typeচ্ছিক টাইপ দুটি ক্ষেত্রে যেমন একটি গণনা ছাড়া কিছুই নয়

 enum Optional<Wrapped> : ExpressibleByNilLiteral {
    case none 
    case some(Wrapped)
    .
    .
    .
}

সুতরাং আমাদের ভেরিয়েবল 'আমি' এর জন্য একটি শিল নিযুক্ত করতে। আমরা করতে var i = Optional<Int>.none বা একটি মূল্য নির্ধারণ করতে , আমরা কিছু মান পাস করব var i = Optional<Int>.some(28)

সুইফ্ট অনুসারে, 'নিল' হ'ল মানের অভাব। এবং এর সাথে সূচনাপ্রাপ্ত একটি উদাহরণ তৈরি করার জন্য nilআমাদের বলা একটি প্রোটোকল অনুসারে চলতে ExpressibleByNilLiteralহবে এবং দুর্দান্ত যদি আপনি এটি অনুমান করেন তবে কেবল Optionalsমেনে চলতে হবে ExpressibleByNilLiteralএবং অন্যান্য ধরণের সাথে মানিয়ে নিরুত্সাহিত করা হবে।

ExpressibleByNilLiteralএর একটি একক পদ্ধতি রয়েছে init(nilLiteral:)যা শূন্যের সাথে একটি ইনস্ট্যাস শুরু করে। আপনি সাধারণত এই পদ্ধতিটিকে কল করবেন না এবং দ্রুত ডকুমেন্টেশন অনুসারে যখনই আপনি nilআক্ষরিক সহ কোনও ptionচ্ছিক প্রারম্ভিককরণ শুরু করেন তখনই সংকলকটি কল করার সাথে সাথে সরাসরি এই আরম্ভকারীটিকে কল করতে নিরুৎসাহিত করা হয় ।

এমনকি আমাকে নিজের মাথাটি around চ্ছিকভাবে ঘিরে রাখতে হবে (কোনও শঙ্কিত উদ্দেশ্য নয়): ডি হ্যাপি সুইফিং অল


12

প্রথমে আপনার জানা উচিত anচ্ছিক মান কী know আপনি বিশদটির জন্য সুইফ্ট প্রোগ্রামিং ভাষায় যেতে পারেন ।

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

আপনি ব্যবহার করতে পারেন if let ...বা guard let ... elseইত্যাদি।

অন্য একটি উপায়, আপনি যদি প্রয়োগের আগে ভেরিয়েবলের অবস্থাটি পরীক্ষা করতে না চান তবে আপনি var buildingName = buildingName ?? "buildingName"পরিবর্তে এটি ব্যবহার করতে পারেন ।


8

আমি যখন সিগু পদ্ধতিটির জন্য প্রস্তুত থেকে আমার আউটলেট মানগুলি সেট করার চেষ্টা করছিলাম তখন আমার এই ত্রুটি হয়েছিল:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let destination = segue.destination as? DestinationVC{

        if let item = sender as? DataItem{
            // This line pops up the error
            destination.nameLabel.text = item.name
        }
    }
}

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

সুতরাং আমি এটি এইভাবে সমাধান করেছি:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let destination = segue.destination as? DestinationVC{

        if let item = sender as? DataItem{
            // Created this method in the destination Controller to update its outlets after it's being initialized and loaded
            destination.updateView(itemData:  item)
        }
    }
}

গন্তব্য নিয়ামক:

// This variable to hold the data received to update the Label text after the VIEW DID LOAD
var name = ""

// Outlets
@IBOutlet weak var nameLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
    nameLabel.text = name
}

func updateView(itemDate: ObjectModel) {
    name = itemDate.name
}

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


updateViewগন্তব্য নিয়ামককে কোথায় কল করতে হবে তা উল্লেখ করতে ভুলবেন না ;)
আহমদ এফ

@ আহমাদএফ ভাল পয়েন্ট তা সত্ত্বেও কলিং updateViewগন্তব্য নিয়ামক মধ্যে এই ক্ষেত্রে প্রয়োজন হয় না হিসাবে আমি ব্যবহার করছি nameসেট করতে পরিবর্তনশীল nameLabel.textমধ্যে viewDidLoad। তবে যদি আমরা প্রচুর সেটআপ করতাম তবে এটি অবশ্যই আরও একটি ফাংশন তৈরি করে এর viewDidLoadপরিবর্তে কল করা ভাল calling
উইসা

7

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

বেশ কয়েকটি পরিস্থিতি রয়েছে যা এই ধরণের মারাত্মক ত্রুটির দিকে পরিচালিত করে:

  1. জোর করে আন-র্যাপস:

    let user = someVariable!

    যদি someVariableশূন্য হয় তবে আপনি ক্রাশ পাবেন। জোর মোড়ক না দিয়ে আপনি কম্পাইলার থেকে নীল চেকের দায়িত্বটি আপনার কাছে সরিয়ে নিয়েছিলেন, মূলত আপনি বাধ্যতামূলকভাবে আন-র‌্যাপ করে আপনি কম্পাইলারের কাছে গ্যারান্টি দিচ্ছেন যে সেখানে আপনার কোনও মূল্য নেই। এবং অনুমান করুন যদি কোনওভাবে কোনও শূন্যের মান শেষ হয় তবে এটি কী ঘটে someVariable?

    সমাধান? Alচ্ছিক বাঁধাই ব্যবহার করুন (ওরফে যদি-দেওয়া হয়), সেখানে ভেরিয়েবল প্রসেসিং করুন:

    if user = someVariable {
        // do your stuff
    }
  2. বাধ্য (নিচে) কাস্ট:

    let myRectangle = someShape as! Rectangle

    এখানে জোর করে ingালাইয়ের মাধ্যমে আপনি সংকলকটিকে আর চিন্তিত হওয়ার জন্য বলবেন না, কারণ আপনার এখানে সর্বদা Rectangleউদাহরণ থাকবে। এবং যতক্ষণ না এটি ধরে রাখে ততক্ষণ আপনাকে চিন্তা করার দরকার নেই। সমস্যাগুলি শুরু হয় যখন আপনি বা আপনার প্রকল্পের সহকর্মীরা অ-আয়তক্ষেত্রের মানগুলি প্রচার শুরু করেন।

    সমাধান? Alচ্ছিক বাঁধাই ব্যবহার করুন (ওরফে যদি-দেওয়া হয়), সেখানে ভেরিয়েবল প্রসেসিং করুন:

    if let myRectangle = someShape as? Rectangle {
        // yay, I have a rectangle
    }
  3. সুস্পষ্টভাবে মোড়কযুক্ত বিকল্পগুলি। ধরে নেওয়া যাক আপনার নিম্নলিখিত শ্রেণীর সংজ্ঞা রয়েছে:

    class User {
        var name: String!
    
        init() {
            name = "(unnamed)"
        }
    
        func nicerName() {
            return "Mr/Ms " + name
        }
    }

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

    সমাধান? এগুলি ব্যবহার করবেন না :) যতক্ষণ না আপনি 102% নিশ্চিত হন যে সম্পত্তিটি ব্যবহারের প্রয়োজন হওয়ার সাথে সাথে সর্বদা একটি অ-শুল্ক মান থাকবে। বেশিরভাগ ক্ষেত্রে anচ্ছিক বা অ-alচ্ছিক রূপান্তর কাজ করবে। এটিকে অ-alচ্ছিক করে তোলার ফলে সেই সংস্থার যে কোড পাথগুলি আপনি সেই সম্পত্তির কোনও মূল্য দিতে মিস করেছেন তা জানিয়ে সংকলক আপনাকে সহায়তা করবে helping

  4. সংযোগযুক্ত, বা এখনও সংযুক্ত নয়, আউটলেটগুলি। এটি # 3 দৃশ্যের একটি বিশেষ কেস। মূলত আপনার কিছু XIB- বোঝা শ্রেণি রয়েছে যা আপনি ব্যবহার করতে চান।

    class SignInViewController: UIViewController {
    
        @IBOutlet var emailTextField: UITextField!
    }

    এখন আপনি যদি XIB সম্পাদক থেকে আউটলেটটি সংযোগ স্থাপন না করে, তবে আপনি আউটলেটটি ব্যবহার করতে চাইলেই অ্যাপটি ক্র্যাশ হয়ে যাবে। সমাধান? নিশ্চিত করুন যে সমস্ত আউটলেট সংযুক্ত রয়েছে। বা ব্যবহার ?তাদের উপর অপারেটর: emailTextField?.text = "my@email.com"। বা আউটলেটটিকে alচ্ছিক হিসাবে ঘোষণা করুন, যদিও এই ক্ষেত্রে সংকলক আপনাকে সমস্ত কোডে এটি মোড়ক করতে বাধ্য করবে।

  5. অবজেক্টিভ-সি থেকে আসা মানগুলি এবং এর মধ্যে অযোগ্যতা টিকা নেই। আসুন ধরে নেওয়া যাক আমাদের নিম্নোক্ত উদ্দেশ্য-সি শ্রেণি রয়েছে:

    @interface MyUser: NSObject
    @property NSString *name;
    @end

    এখন যদি কোনও অকারণযোগ্যতা টীকাগুলি নির্দিষ্ট করা হয় না (হয় স্পষ্টভাবে বা NS_ASSUME_NONNULL_BEGIN/ মাধ্যমে NS_ASSUME_NONNULL_END), তবে nameসম্পত্তিটি String!সুইফটে (একটি আইইউও - স্পষ্টতভাবে মোড়কযুক্ত .চ্ছিক) হিসাবে আমদানি করা হবে । যত তাড়াতাড়ি কিছু সুইফ্ট কোড মানটি ব্যবহার করতে চাইবে, তা যদি nameশূন্য হয় তবে ক্রাশ হবে ।

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


2

এটি আরও একটি গুরুত্বপূর্ণ মন্তব্য এবং এটি যে ডিবাগিংয়ের nilমানগুলির ক্ষেত্রে স্পষ্টতভাবে মোড়কযুক্ত বিকল্পগুলি বিভ্রান্তিকর হতে পারে ।

নিম্নলিখিত কোডটি ভাবুন: এটি কোনও ত্রুটি / সতর্কতা সহ সংকলন করে:

c1.address.city = c3.address.city

তবু রানটাইমের সময় এটি নিম্নলিখিত ত্রুটিটি দেয়: মারাত্মক ত্রুটি: অপশনালিকৃত মানটি মোড়ক করার সময় অপ্রত্যাশিতভাবে শৃঙ্খলা রক্ষা পাওয়া যায়

আপনি কি বলতে পারেন কোন বস্তু nil?

আপনি পারবেন না!

সম্পূর্ণ কোডটি হ'ল:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        var c1 = NormalContact()
        let c3 = BadContact()

        c1.address.city = c3.address.city // compiler hides the truth from you and then you sudden get a crash
    }
}

struct NormalContact {
    var address : Address = Address(city: "defaultCity")
}

struct BadContact {
    var address : Address!
}

struct Address {
    var city : String
}

var address : Address!আপনি ব্যবহার করে একটি দীর্ঘ গল্প সংক্ষিপ্তসারটি সম্ভবত অন্য পাঠকদের থেকে পরিবর্তনশীল হতে পারে এমন সম্ভাবনাটি লুকিয়ে রাখে nil। এবং যখন এটি ক্র্যাশ হয় তখন আপনি "কী addressহ'ল ! আমার কোনও optionচ্ছিক নয়, তাই কেন আমি ক্র্যাশ করছি?!।"

সুতরাং এটি যেমন লিখতে ভাল:

c1.address.city = c2.address!.city  // ERROR:  Fatal error: Unexpectedly found nil while unwrapping an Optional value 

আপনি কি আমাকে বলতে পারেন যে এটি কোন বস্তুটি ছিল nil?

এবার কোডটি আপনার কাছে আরও স্পষ্ট করে দেওয়া হয়েছে। আপনি যুক্তিযুক্ত করতে এবং ভাবতে পারেন যে এটি সম্ভবত এমন addressপ্যারামিটার যা জোর করেই মোড়ানো ছিল।

সম্পূর্ণ কোডটি হ'ল:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        var c1 = NormalContact()
        let c2 = GoodContact()

        c1.address.city = c2.address!.city
        c1.address.city = c2.address?.city // not compile-able. No deceiving by the compiler
        c1.address.city = c2.address.city // not compile-able. No deceiving by the compiler
        if let city = c2.address?.city {  // safest approach. But that's not what I'm talking about here. 
            c1.address.city = city
        }

    }
}

struct NormalContact {
    var address : Address = Address(city: "defaultCity")
}

struct GoodContact {
    var address : Address?
}

struct Address {
    var city : String
}

2

ত্রুটিগুলি EXC_BAD_INSTRUCTIONএবং স্টোরিবোর্ডের সাথে সংযুক্ত না হয়ে fatal error: unexpectedly found nil while implicitly unwrapping an Optional valueযখন আপনি একটি ঘোষণা করেন তখন সর্বাধিক প্রদর্শিত হয় ।@IBOutlet

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


করা উচিত নয় @IBOutletএই ত্রুটি কারণ আছে অপ্রত্যাশিতভাবে শূন্য সময় পাওয়া যায়নি: মারাত্মক ত্রুটি পরোক্ষভাবে একটি ঐচ্ছিক মান unwrapping ত্রুটির সংস্করণ?
pkamb

1
সেটা সত্য. আমি যখন উত্তরটি প্রেরণ করি তখন যা আমি বলতে চাইছিলাম এবং আমি প্রথম মারাত্মক ত্রুটি বার্তাটি অনুলিপি করেছি। হামিশের উত্তর এই সম্পর্কে খুব সম্পূর্ণ দেখায়।
আলে মোহামাদ

2

আপনি যদি কালেকশনভিউতে এই ত্রুটিটি পান তবে কাস্টমসেল ফাইল এবং কাস্টম এক্সিবও তৈরি করার চেষ্টা করুন।

মেইনভিসিতে ভিডিডলিড () এ এই কোডটি যুক্ত করুন।

    let nib = UINib(nibName: "CustomnibName", bundle: nil)
    self.collectionView.register(nib, forCellWithReuseIdentifier: "cell")

0

টেবিল ভিউ কন্ট্রোলার থেকে একটি ভিউ কন্ট্রোলারে সিগ তৈরি করার সময় আমি এই ত্রুটিটি পেরিয়ে এসেছি কারণ আমি মূল স্টোরিবোর্ডে ভিউ কন্ট্রোলারের জন্য কাস্টম শ্রেণীর নাম নির্দিষ্ট করতে ভুলে গিয়েছিলাম।

অন্য কিছু ঠিক আছে কিনা তা যাচাই করার জন্য এমন কিছু সাধারণ পরীক্ষা

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