যুক্তি সহ সুইফ্ট ব্লকগুলিতে কীভাবে সঠিকভাবে পরিচালনা করতে হয়


151

আমার মধ্যে TextViewTableViewCell, আমার কাছে একটি ব্লক এবং একটি কনফিগার পদ্ধতি যেখানে ব্লকটি প্রবেশ করানো হয়েছে এবং নির্ধারিত হয়েছে তার ট্র্যাক রাখতে আমার একটি পরিবর্তনশীল রয়েছে।
এখানে আমার TextViewTableViewCellক্লাস:

//
//  TextViewTableViewCell.swift
//

import UIKit

class TextViewTableViewCell: UITableViewCell, UITextViewDelegate {

    @IBOutlet var textView : UITextView

    var onTextViewEditClosure : ((text : String) -> Void)?

    func configure(#text: String?, onTextEdit : ((text : String) -> Void)) {
        onTextViewEditClosure = onTextEdit
        textView.delegate = self
        textView.text = text
    }

    // #pragma mark - Text View Delegate

    func textViewDidEndEditing(textView: UITextView!) {
        if onTextViewEditClosure {
            onTextViewEditClosure!(text: textView.text)
        }
    }
}

আমি যখন আমার cellForRowAtIndexPathপদ্ধতিতে কনফিগার পদ্ধতিটি ব্যবহার করি, তখন আমি যে ব্লকটিতে প্রবেশ করি সেখানে কীভাবে দুর্বল স্বকে সঠিকভাবে ব্যবহার
করব the দুর্বল স্ব ছাড়া আমার যা আছে তা এখানে:

let myCell = tableView.dequeueReusableCellWithIdentifier(textViewCellIdenfitier) as TextViewTableViewCell
myCell.configure(text: body, onTextEdit: {(text: String) in
   // THIS SELF NEEDS TO BE WEAK  
   self.body = text
})
cell = bodyCell

আপডেট : আমি নিম্নলিখিতটি ব্যবহার করে কাজ করেছি [weak self]:

let myCell = tableView.dequeueReusableCellWithIdentifier(textViewCellIdenfitier) as TextViewTableViewCell
myCell.configure(text: body, onTextEdit: {[weak self] (text: String) in
        if let strongSelf = self {
             strongSelf.body = text
        }
})
cell = myCell

আমি [unowned self]পরিবর্তে যখন করি [weak self]এবং ifবিবৃতিটি বের করি তখন অ্যাপটি ক্র্যাশ হয়ে যায়। এটি কীভাবে কাজ করবে সে সম্পর্কে কোনও ধারণা [unowned self]?


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

1
আমি বুঝতে পারি যে [অপরিশোধিত স্ব] যদি আরও ভাল বিকল্প হয় তবে আমার অ্যাপটি যখন আমি এটি ব্যবহার করি তখন ক্রাশ হয়। উত্তরটি বন্ধ করার জন্য একটি কোড নমুনা এটি ব্যবহার করতে পছন্দ করবে।
নাতাশাআরবোট

1
দস্তাবেজগুলি থেকে: "দুর্বল রেফারেন্সগুলির মতো, অবাঞ্ছিত রেফারেন্স যেমন উল্লেখ করা হয়েছে তেমন দৃ hold়ভাবে ধরে না। সম্ভবত অজ্ঞাতসারে এমন কোনও মান প্রয়োগ করা হচ্ছে যা রানটাইমের সময় শূন্য নয়।
বিল প্যাটারসন

বলিষ্ঠ সেলফের কাছে বাধ্যতামূলক না হওয়ার চেয়ে এখানে কোনও গার্ড স্টেটমেন্টের বিজ্ঞাপন দেওয়া ভাল। শুধু বলছি, এটি নিখুঁত প্রার্থীর মতো:
ডি

@ নাতাশাওরোবট, [দুর্বল স্ব] সিনট্যাক্সটি কী? উদ্দেশ্য সি তে একটি বার্তা প্রেরণ করা মনে হচ্ছে আপনি কি দয়া করে প্রশ্নে বাক্য গঠন সম্পর্কে আরও কিছু যোগ করতে পারেন।
ভগ্নেশ

উত্তর:


178

যদি স্ব অবসান ব্যবহারে শূন্য হতে পারে [দুর্বল স্ব]

যদি স্বাবলম্বন কখনই বন্ধের ব্যবহারে [অচেতন স্ব] নিরস্ত হয় না

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

শক্তিশালী , দুর্বল এবং বন্ধ অবস্থায় অবহেলিত ব্যবহারের জন্য ম্যানুয়াল থেকে পুরো অংশটি আমি সত্যিই পছন্দ করেছি :

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html

দ্রষ্টব্য: আমি ব্লকের পরিবর্তে ক্লোজার শব্দটি ব্যবহার করেছি যা নতুন সুইফট শব্দ:

আইওএসে ব্লক (উদ্দেশ্য সি) এবং বন্ধকরণ (সুইফট) এর মধ্যে পার্থক্য


7
অ্যাপল ব্লকগুলিকে সি ভাষা সম্প্রসারণের জন্য তাদের প্রথম দস্তাবেজে "ক্লোজার" বলে অভিহিত করেছে। (ব্লক বা ক্লোজারগুলি একেবারে প্রথমদিকে সি এর একটি এক্সটেনশন Only কেবলমাত্র এমএম উদ্দেশ্য-সি সম্পর্কিত is) এমনকি আমি "ক্লোজার" শব্দটিও পছন্দ করি, কারণ সিতে "ব্লকগুলি" যৌগিক বিবৃতিগুলির সাথে প্রায়শই সম্পর্কিত, এটি উভয় ভাষায় এক ধরণের ভুল, কারণ এটি একটি ক্লোজার বলা হয় এমনকি এটি কোনও বস্তুর (পরিবর্তনশীল বা ধ্রুবক) এর কাছাকাছিও আসে না।
আমিন নেগম-আওয়াদ

1
খুব সুন্দর উত্তর দিয়েছেন :)
iDevAmit

1
আমি কখনই ব্যবহার না করার পরামর্শ দেব unowned। আপনার অ্যাপ্লিকেশনটি ক্রাশ হওয়ার ঝুঁকিটি মূল্যহীন।
কাইল রেডফারন

32

আপনার বন্ধের [unowned self]আগে রাখুন (text: String)...। একে ক্যাপচার তালিকা বলা হয় এবং বন্ধের মধ্যে বন্দী প্রতীকগুলির উপর মালিকানার নির্দেশাবলী রাখে।


2
নামকরণের জন্য ধন্যবাদ, আমি এটি জানতে চেয়েছিলাম!
rob5408

3
এই উত্তরটি কার্যকর বলে আমি মনে করি না। [অচেতন স্ব] বন্ধের ফাঁসি কার্যকর করার সময় যদি নিজেকে নিঃশব্দ করা হয় তবে দুর্ঘটনা ঘটবে
ইউনূস নেদিম মেহেল

3
আছে একেবারে কোন কারণ মধ্যে মালিকহীন ব্যবহার করার জন্য, চেয়ে (1) অন্যান্য অত্যন্ত অস্বাভাবিক পরিস্থিতিতে পারফরম্যান্সের জন্য, এবং (2) (এখানে এবং প্রোগ্রামিং 99.999% মধ্যে একদম অপ্রাসঙ্গিক) একটি শৈলী-প্রয়োগকারী বিষয় হিসাবে। "আপনার সর্বদা দুর্বল, অজানা কখনও ব্যবহার করা উচিত নয়" উক্তিটি খুব যুক্তিসঙ্গত।
ফ্যাটি

29

** সুইফট ৪.২-এর জন্য সম্পাদিত:

@ কোইন যেমন মন্তব্য করেছে, তত দ্রুত সুইচ ৪.২ অনুমতি দেয়:

guard let self = self else {
   return // Could not get a strong reference for self :`(
}

// Now self is a strong reference
self.doSomething()

পিএস: যেহেতু আমার কিছুটা বেশি ভোট হচ্ছে, তাই আমি ক্লোসারের হাত থেকে বাঁচার বিষয়ে পড়ার পরামর্শ দিতে চাই ।

সম্পাদনা: @ টাইম-ভার্মিউলেন যেমন মন্তব্য করেছেন, ক্রিস ল্যাটনার শুক্রবার 22 জানুয়ারী 19:51:29 সিএসটি 2016 তে বলেছেন, এই কৌশলটি নিজের উপর ব্যবহার করা উচিত নয়, দয়া করে এটি ব্যবহার করবেন না। @Gbk থেকে অব্যাহতিপ্রাপ্ত বন্ধের তথ্য এবং ক্যাপচার তালিকার উত্তর পরীক্ষা করুন Check **

ক্যাপচার তালিকায় যারা [দুর্বল স্ব] ব্যবহার করেন তাদের জন্য নোট করুন যে স্বটি শূন্য হতে পারে, তাই আমি প্রথমে যা করি তা হ'ল একজন গার্ড স্টেটমেন্ট সহ এটি পরীক্ষা করা

guard let `self` = self else {
   return
}
self.doSomething()

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


2
`স্ব` ছায়াকরণ একটি নমুনা, এটা সম্পর্কে একটি নিবন্ধ পাওয়া যাবে এখানে arsenkin.com/swift-closure-without-ugly-strongSelf.html
কালেন সান

2
আমি স্থানীয় "স্ব" "বলিষ্ঠ সেল্ফ" কে কল করতে চাই যাতে এটি ডিফল্ট আত্মের সাথে বিভ্রান্ত না হয় এবং আপনি শক্তিশালী স্ব-রেফারেন্সের জন্য সুরক্ষিত ছিলেন কিনা তা খুঁজে পাওয়া সহজ।
জাস্টিন স্ট্যানলি

1
এটি ব্যবহার করা উচিত নয়, কারণ এটি একটি সংকলক বাগ: list.swift.org/pipermail/swift-evolution/Week-of- Mon
টিম ভার্মিউলেন

1
আমি মনে করি উপরের লিঙ্কে ক্রিস ল্যাটনার মন্তব্যটি কেবলমাত্র self(ব্যাকটিক্সে) পরিবর্তকের নামকরণ না করার বিষয়ে । একে অন্যরকম নাম দিন যেমন নন-অপশনালসেলফ এবং এটি ঠিক থাকবে।
আউটআউই উইন্ডেন্ড 20

1
আজকাল ( সুইফ্ট ৪.২) { [weak self] in guard let self = self else { return }ব্যাকটিক্স ছাড়াই ব্যবহার করা যায় এবং এটি আসলে সমর্থিত: github.com/apple/swift-evolution/blob/master/proposals/…
কোয়েন।

26

ক্যাপচার তালিকাটি ব্যবহার করুন

ক্যাপচার তালিকার সংজ্ঞা দেওয়া হচ্ছে

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

বন্ধ করার প্যারামিটার তালিকার আগে ক্যাপচার তালিকাটি রাখুন এবং যদি সরবরাহ করা হয় তবে তা ফেরতের প্রকার:

lazy var someClosure: (Int, String) -> String = {
    [unowned self, weak delegate = self.delegate!] (index: Int, stringToProcess: String) -> String in
    // closure body goes here 
} 

যদি কোনও ক্লোজার কোনও প্যারামিটার তালিকা বা রিটার্নের ধরণ নির্দিষ্ট না করে কারণ সেগুলি প্রসঙ্গ থেকে অনুমান করা যায়, বন্ধ করার খুব প্রথম দিকে ক্যাপচার তালিকাটি রাখুন, তারপরে কীওয়ার্ডটি অনুসরণ করুন:

lazy var someClosure: Void -> String = {
    [unowned self, weak delegate = self.delegate!] in
    // closure body goes here
}

অতিরিক্ত ব্যাখ্যা


3
আপনি "স্ব" -এর জন্য অপরিবর্তিত ব্যবহার করেছেন যার অর্থ আপনি যখন নিশ্চিত হন "স্ব" আপনি যখন এটি অ্যাক্সেস করবেন তখন নিঃশব্দ হবে। তারপরে আপনি এটিকে দুর্বল ভারে নির্ধারণের জন্য "সেলফ ডেলিগেট" (যার অর্থ আপনি এটি নিশ্চিত নন যে এটি নিশ্চিতভাবেই জানেন) এর উপর আন-মোড়কে বল প্রয়োগ করা হয়েছিল। আপনি যদি নিশ্চিতভাবেই জানেন যে "সেলফ ডেলিগেট" শূন্য করে না তবে দুর্বল হওয়ার পরিবর্তে "প্রতিনিধি" এর উপরে অবজ্ঞাত ব্যবহার না করে কেন?
রনি লেশেস

26

সম্পাদনা: লাইটম্যান দ্বারা আপডেট করা সমাধানের উল্লেখ

দেখুন LightMan এর সমাধান । এখন অবধি আমি ব্যবহার করছিলাম:

input.action = { [weak self] value in
    guard let this = self else { return }
    this.someCall(value) // 'this' isn't nil
}

বা:

input.action = { [weak self] value in
    self?.someCall(value) // call is done if self isn't nil
}

সাধারণত প্যারামিটারের ধরণটি যদি অনুমান করা হয় তবে আপনাকে নির্দিষ্ট করার দরকার নেই।

আপনি যদি প্যারামিটারটি সম্পূর্ণরূপে বাদ দিতে পারেন তবে কিছুই নেই বা আপনি $0যদি এটি বন্ধ হিসাবে উল্লেখ করেন:

input.action = { [weak self] in
    self?.someCall($0) // call is done if self isn't nil
}

কেবল সম্পূর্ণতার জন্য; যদি আপনি কোনও ফাংশনে ক্লোজারটি পাস করে থাকেন এবং প্যারামিটারটি না হয় তবে @escapingআপনার একটি দরকার নেই weak self:

[1,2,3,4,5].forEach { self.someCall($0) }

9

দ্রুত 4.2 🔸 হিসাবে আমরা করতে পারি:

_ = { [weak self] value in
    guard let self = self else { return }
    print(self) //👈 will never be nil
}()

অন্যদের মতো সমাধান রয়েছে তবে "এটি" হ'ল সি ++ আইএমএইচও। "বলিষ্ঠসেল্ফ" হ'ল একটি অ্যাপল কনভেনশন এবং আপনার কোডটিতে যে কেউ নজর রাখেন সে কী হবে তা জানতে পারে।
ডেভিড এইচ

1
@ ডেভিড এইচ আইএমও বাক্যাংশটি strongSelfস্পষ্টভাবে ভেরিয়েবলের অর্থ / পার্শ্ব প্রতিক্রিয়া ব্যাখ্যা করে যা কোডটি যদি আরও দীর্ঘ প্রকৃতির হয় তবে তা দুর্দান্ত। আপনার মতামত প্রশংসা যদিও, সি ++ এই ধরনের শব্দচয়ন ব্যবহৃত জানেন না।
ইনিস্ট

3
সুইফট 4.2 এর হিসাবে আপনি ব্যবহার করতে পারেন guard let self = self else { return }থেকে মোড়ক খোলা [weak self]: github.com/apple/swift-evolution/blob/master/proposals/...
আমের Hukic

@ আমারহুকিক
ইনিস্ট


3

আপনার ব্লকের পরামিতিগুলির পূর্বে আপনি ক্যাপচার তালিকায় [দুর্বল স্ব] বা [অজানা স্ব] ব্যবহার করতে পারেন। ক্যাপচার তালিকাটি alচ্ছিক সিনট্যাক্স।

[unowned self]এখানে ভাল কাজ করে কারণ ঘরটি কখনই শূন্য হয় না। অন্যথায় আপনি ব্যবহার করতে পারেন[weak self]


1
সেলটি স্বয়ং নয়, তিনি কোষের ক্লাসে নেই, তিনি সম্ভবত একজন ভিউকন্ট্রোলারের উপরে রয়েছেন ...
হুয়ান

0

আপনি যদি প্রয়োজনের চেয়ে ক্রাশ হয়ে থাকেন তবে সম্ভবত [দুর্বল স্ব] প্রয়োজন

আমার অনুমান যে আপনি যে ব্লকটি তৈরি করছেন তা এখনও কোনওরকমভাবে বিরল।

একটি প্রস্তুতিফরিউজ তৈরি করুন এবং এর ভিতরে টেক্সটভিউএডিটক্লোজার ব্লকটি সাফ করার চেষ্টা করুন।

func prepareForResuse() {
   onTextViewEditClosure = nil
   textView.delegate = nil
}

দেখুন যে এটি ক্রাশ প্রতিরোধ করে কিনা। (এটি কেবল অনুমান)।


0

বন্ধ এবং শক্তিশালী রেফারেন্স চক্র [সম্পর্কে]

আপনি জানেন যে সুইফটের বন্ধটি উদাহরণটি ক্যাপচার করতে পারে। এর অর্থ হ'ল আপনি selfএকটি বন্ধের ভিতরে ব্যবহার করতে পারবেন । বিশেষত escaping closure[সম্পর্কে]strong reference cycle যা তৈরি করতে পারে । উপায় দ্বারা আপনাকে স্পষ্টভাবে selfভিতরে ব্যবহার করতে হবে escaping closure

সুইফ্ট ক্লোজারটিতে এমন Capture Listবৈশিষ্ট্য রয়েছে যা আপনাকে এ জাতীয় পরিস্থিতি এড়াতে এবং একটি রেফারেন্স চক্র ভাঙতে দেয় কারণ ক্যাপচারিত দৃষ্টান্তটির দৃ strong় উল্লেখ নেই। ক্যাপচার তালিকার উপাদানটি weak/ unownedএবং ক্লাস বা ভেরিয়েবলের একটি উল্লেখ a

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

class A {
    private var completionHandler: (() -> Void)!
    private var completionHandler2: ((String) -> Bool)!

    func nonescapingClosure(completionHandler: () -> Void) {
        print("Hello World")
    }

    func escapingClosure(completionHandler: @escaping () -> Void) {
        self.completionHandler = completionHandler
    }

    func escapingClosureWithPArameter(completionHandler: @escaping (String) -> Bool) {
        self.completionHandler2 = completionHandler
    }
}

class B {
    var variable = "Var"

    func foo() {
        let a = A()

        //nonescapingClosure
        a.nonescapingClosure {
            variable = "nonescapingClosure"
        }

        //escapingClosure
        //strong reference cycle
        a.escapingClosure {
            self.variable = "escapingClosure"
        }

        //Capture List - [weak self]
        a.escapingClosure {[weak self] in
            self?.variable = "escapingClosure"
        }

        //Capture List - [unowned self]
        a.escapingClosure {[unowned self] in
            self.variable = "escapingClosure"
        }

        //escapingClosureWithPArameter
        a.escapingClosureWithPArameter { [weak self] (str) -> Bool in
            self?.variable = "escapingClosureWithPArameter"
            return true
        }
    }
}
  • weak- আরও ভাল, এটি সম্ভব হলে এটি ব্যবহার করুন
  • unowned - যখন আপনি নিশ্চিত হন যে দৃষ্টান্তের মালিকের জীবনকাল বন্ধ হওয়ার চেয়ে বড়
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.