সংকলক ত্রুটি: একই উদ্দেশ্য-সি নির্বাচকের সাথে পূর্ববর্তী ঘোষণার সাথে উদ্দেশ্য-সি নির্বাচকের বিবাদগুলির সাথে পদ্ধতি


209

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

সুইফট সহ আইওএস 8 অ্যাপ্লিকেশন বিকাশ করছে - 2. আরও এক্সকোড এবং সুইফট, এমভিসি

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

কোডটি যা ত্রুটি তৈরি করে তা হ'ল:

import UIKit

class BugViewController: UIViewController
{
    func perform(operation: (Double) -> Double) {
    }

    func perform(operation: (Double, Double) -> Double) {
    }
}

এটি নিম্নলিখিত সংকলক ত্রুটি তৈরি করে:

উদ্দেশ্য-সি নির্বাচকের সাথে 'পারফর্ম' পদ্ধতি 'পারফর্ম:' একই উদ্দেশ্য-সি নির্বাচকের সাথে পূর্ববর্তী ঘোষণার সাথে দ্বন্দ্ব

কেবল কোড সংকলনগুলি ইউআইভিউউকন্ট্রোলারের উপ-শ্রেণিবদ্ধকরণ সরিয়ে:

import UIKit

class BugViewController
{
    func perform(operation: (Double) -> Double) {
    }

    func perform(operation: (Double, Double) -> Double) {
    }
}

প্রাসঙ্গিক বা নাও হতে পারে এমন আরও কিছু তথ্য:

  • আমি সম্প্রতি ইয়োসেমাইটে আপগ্রেড করেছি।
  • যখন আমি এক্সকোড ইনস্টল করেছি, আমি একটি বিটা সংস্করণ (সংস্করণ 6.3 (6D543q)) দিয়ে শেষ করেছি কারণ (যদি আমি সঠিকভাবে মনে করি) এটি আমার ওএস এক্স এর সংস্করণে চালানোর জন্য প্রয়োজনীয় সংস্করণ ছিল

আমি অর্ধেক আশা করছি এটি সংকলকটিতে একটি বাগ আছে কারণ অন্যথায় এটি আমার কোনও অর্থ দেয় না। খুব কৃতজ্ঞভাবে কোনও সহায়তা প্রাপ্ত!


3
আপনি ইয়োসেমাইটে এক্সকোড 6.2 চালাতে পারেন। আপনি এটি অ্যাপ স্টোর থেকে ডাউনলোড করতে পারেন এবং এটি আপনার সিস্টেমে বিটা সংস্করণ সহ লাইভ করতে পারে। আমি স্ট্যানফোর্ড ক্লাসের জন্য এই মুহুর্তে এক্সকোড .3.৩ ব্যবহার করার পরামর্শ দেব না কারণ এটি বিটাতে এবং সুইফট ১.২ অন্তর্ভুক্ত করে যা ভিডিওতে ব্যবহৃত সুইফটের আগের সংস্করণটি থেকে আলাদা।
ওয়াকওমা

2
5 এপ্রিল থেকে ব্যবহারকারীদের (ফেবি) উত্তর (বর্তমানে গৃহীত) উত্তর আর সেরা নয়। পরিবর্তে 16 এপ্রিল থেকে (জেমস জাং) এর উত্তর আরও সুনির্দিষ্ট এবং সঠিক।
ফ্লেবোটিনাম

উত্তর:


144

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


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

: @ নিচে polarwar এর উত্তর সুইফট 2 জন্য শ্রেষ্ঠ এক stackoverflow.com/a/31500740/144088
Crashalot

237

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

সুইফট ১.২ @ ওবিজেসি পদ্ধতি এবং ইনিশিয়ালাইজারগুলির টাইপ-ভিত্তিক ওভারলোডিং চেক করা সম্পর্কে কঠোর, যা উদ্দেশ্য-সি দ্বারা সমর্থিত নয়।

// Has the Objective-C selector "performOperation:".
func performOperation(op: NSOperation) { /* do something */ }
// Also has the selector "performOperation:".
func performOperation(fn: () -> Void) {
    self.performOperation(NSBlockOperation(block: fn))
}

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

  • যদি এটি উপলব্ধি করে তবে @objc এর অনুমিতি অক্ষম করতে সদস্যটিকে ব্যক্তিগত হিসাবে চিহ্নিত করুন।
  • অন্যথায়, ডিফল্ট মান সহ একটি ডামি প্যারামিটার ব্যবহার করুন, উদাহরণস্বরূপ: _ nonobjc: () = ()। (19826275)

বেসরকারী সাবক্লাসগুলিতে অবজেক্টিভ-সি-তে উদ্ভাসিত পদ্ধতির ওভাররাইডগুলি @objc বলে অনুমান করা হয় না, যার ফলে সুইফ্ট সংকলক ক্র্যাশ হয়ে যায়। স্পষ্টভাবে এই জাতীয় ওভাররাইড পদ্ধতিতে @objc বৈশিষ্ট্য যুক্ত করুন। (19935352)

সুইড্ট ব্যবহার করে এমন কোনও প্রকল্পে বা ওয়ার্কস্পেসে দ্রুত ওপেন ব্যবহার করার সময় এসডিকে থেকে চিহ্নগুলি পাওয়া যায় না। (20349540)

আমি যা করেছি তা কেবল ওভাররাইড পদ্ধতির সামনে "ব্যক্তিগত" যুক্ত ছিল:

    private func performOperation(operation: Double -> Double) {
    if operandStack.count >= 1 {
        displayValue = operation(operandStack.removeLast())
        enter()
    }
}

3
এই সমাধান, সবচেয়ে টেকসই আমি খুঁজে এই প্রোগ্রামটিতে হিসাবে এই সম্পূর্ণই এই পদ্ধতি বেসরকারী সেট করতে ইন্দ্রিয় তোলে
demental

38
দয়া করে নোট করুন যে এখন একটি @nobjc বৈশিষ্ট্য রয়েছে, যা উদ্দেশ্য-সি রানটাইম থেকে কোনও পদ্ধতি বাদ দিতে ব্যবহার করা যেতে পারে।
এরিক জে

2
আমি দ্বিতীয় @ এরিকজে এর মন্তব্য এবং নীচে পোলারওয়ার এর উত্তর। এটি সুইফট 2 এবং এক্সকোড 7 দিয়ে এগিয়ে যাওয়ার সেরা উত্তর বলে মনে হচ্ছে আপনি যদি এখনও আপডেট না করেন তবে আমি দৃ strongly়ভাবে এটির প্রস্তাব দিই।
অস্টিন এ 21

: @ নিচে polarwar এর উত্তর সুইফট 2 জন্য শ্রেষ্ঠ এক stackoverflow.com/a/31500740/144088
Crashalot

111

যেমন ইতিমধ্যে উত্তর দেওয়া হয়েছে, ওবিজেসি পদ্ধতি ওভারলোডিং (একই নামের দুটি পদ্ধতি) এবং এক্সকোড 7 এর অধীনে সুইফট 2 এ এই ধরণের সমস্যাগুলি সমাধান করার জন্য দুটি বিকল্প রয়েছে support একটি বিকল্প হ'ল বৈশিষ্ট্যটি ব্যবহার করে পদ্ধতিটির নামকরণ:@objc(newNameMethod:)

func methodOne(par1, par2) {...}

@objc(methodTwo:)
func methodOne(par1) {...}

এক্সকোড ++ এ এই সমস্যাটি সমাধান করার জন্য অন্য বিকল্পটি হ'ল @nonobjcযে কোনও পদ্ধতি, সাবস্ক্রিপ্ট বা ইনিশিয়ালাইজারের বৈশিষ্ট্য প্রয়োগ করে

func methodOne() {...}

@nonobjc
func methodOne() {...}

6
এটি সুইফট 2 (এবং উপরে) এর জন্য সমস্যার সমাধান করে। সবচেয়ে সঠিক উত্তর হিসাবে আপডেট করা উচিত। TY।
ম্যাক্সিম ভেক্সলার

2
যে কেউ সুইফট 2 এবং এক্সকোড 7 + ব্যবহার করে
এটির

17

সমস্যাটি UIViewControllerএক @objcশ্রেণির। যখন থেকে উত্তরাধিকার সূত্রে প্রাপ্ত UIViewController, BugViewControllerএকটি হল @objcবর্গ।

এর অর্থ এটি অবশ্যই উদ্দেশ্য-সি নির্বাচকদের (কোনও পদ্ধতির নাম) নিয়ম মেনে চলতে হবে। পদ্ধতি func perform(operation: (Double) -> Double)এবং func perform(operation: (Double, Double) -> Double)উভয় একই নির্বাচক আছে @selector(perform:)। এই অনুমতি দেওয়া হয় না.

এটি সমাধান করতে, বিভিন্ন নাম ব্যবহার করুন: পছন্দ করুন func perform1(operation: (Double) -> Double)এবং func perform2(operation: (Double, Double) -> Double)


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


ধন্যবাদ - এটি আমার প্রশ্নের সঠিক উত্তর দেয় এবং আপনি প্রথম হিসাবে আমি এটিকে সঠিক হিসাবে চিহ্নিত করব।
এপ্রিস

বলার পরেও আমি এখনও বুঝতে পারছি না যে লেকচারের কোডটি কেন কাজ করেছিল কারণ আমি যথেষ্ট নিশ্চিত যে এটি আমার অ-সংকলন কোডটি করেছে! আরে হো - আমি ফিরে যাব এবং এটি ডাবল চেক করব। কিছু আলাদা থাকতে হবে।
এপ্রিস

2
@ অ্যাসপিস এটি ভিডিওগুলির জন্য Xcode এর সংস্করণে ত্রুটি তৈরি করতে পারে নি তবে এটি এখনও একটি সমস্যা ছিল was এটি Xcode 6.3 অবধি ছিল না যে সংকলকটি এটি আপনাকে সতর্ক করার জন্য সনাক্ত করতে সক্ষম হয়েছিল।
মিক ম্যাককালাম

3
পল হেগার্টি এখানে ফাংশন 'ওভারলোডিং' প্রদর্শন করতে চান (একই নামে 2 টি ফাংশন, তবে বিভিন্ন যুক্তি যুক্ত), তাই তিনি একই পদ্ধতির নামটি উদ্দেশ্য হিসাবে ব্যবহার করেন! ওভারলোডিং কেবলমাত্র সুইফটে অনুমোদিত, উদ্দেশ্য-সি-তে নয়। সে কারণেই সমাধানটি হয় উত্তরাধিকার ফর্ম ইউআইভিউকন্ট্রোলার (যা একটি উদ্দেশ্য-সি শ্রেণি) সরানো, বা পদ্ধতিটি ব্যক্তিগত হিসাবে ঘোষণা করা। উভয় সমাধান এখানে অন্যান্য উত্তর বিস্তারিতভাবে ব্যাখ্যা করা হয়।
রনি ওয়েবার্স

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

5

"এক্সকোড .3.৩ রিলিজ নোটস" -> "স্যুইফট ল্যাঙ্গুয়েজের পরিবর্তনসমূহ" এর আওতায় https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc6_release_notes.html থেকে

সুইফট এখন সুইফট টাইপ সিস্টেমে ওভারলোডিং ও ওভাররাইডিং এবং ওজেক্টিভ-সি রানটাইমের মাধ্যমে কার্যকর কার্যকর আচরণের মধ্যে পার্থক্য সনাক্ত করে।


2

একই ওবজে-সি স্বাক্ষর সহ দুটি পদ্ধতি থাকার কারণে আমি একই ত্রুটি পেয়েছি:

static func prepareForUpSyncing(obj : NSManagedObject!) -> Bool
static func prepareForUpSyncing(objs : [NSManagedObject]!) -> Bool

রানটাইমে অস্বাভাবিক পরিণতির সম্ভাবনার কারণে আমি তাদের মধ্যে একটিকে @ ননোবজেসি হিসাবে চিহ্নিত করতে চাইনি। (কোনও সম্ভাবনা না থাকলে কেউ আমাকে সংশোধন করতে পারে)

সুইফটের বাইরের প্যারামিটার নাম বৈশিষ্ট্যটি (আমি বাহ্যিক নামটিকে স্থানীয় নাম হিসাবে একই বানিয়েছি) দ্বিতীয় পদ্ধতিতে ব্যবহার করে এটি সমাধান করেছি, যা কার্যকরভাবে ওবজ-সি পদ্ধতিতে স্বাক্ষর পরিবর্তন করে:

static func prepareForUpSyncing(objs objs : [NSManagedObject]!) -> Bool {
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.