ios - كيفية التعامل بشكل صحيح ضعيفة الذاتي في كتل سويفت مع الحجج




swift retain-cycle (6)

في 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 بي ، كيف يمكنني استخدام الضعف الذاتي في الكتلة التي cellForRowAtIndexPath بشكل صحيح.
هنا ما لدي دون ضعف النفس:

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] ؟


استخدم اسم strongSelf ، فهو أكثر وضوحا من IMO

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

إذا كان النفس يمكن أن يكون لا شيء في استخدام الإغلاق [النفس الضعيف] .

إذا كان النفس لن يكون أبدا الصفر في استخدام الإغلاق [النفس غير المملوءة] .

إذا تحطمت عندما تستخدم [الذات غير المملوءة] ، فإنني أعتقد أن النفس لا شيء في نقطة معينة في هذا الإغلاق ، وهذا هو السبب في أنك اضطرت إلى الذهاب مع [ضعيفة النفس] بدلاً من ذلك.

أنا حقا أحب المقطع كله من دليل على استخدام قوي ، وضعف ، وغير مملوك في الإغلاق:

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

ملاحظة: استخدمت مصطلح الإغلاق بدلاً من الحظر وهو مصطلح سويفت الأحدث:

الفرق بين الكتلة (الهدف C) والإغلاق (Swift) في ios


استخدم قائمة الالتقاط

تحديد قائمة القبض

كل عنصر في قائمة الالتقاط هو إقران الكلمة الرئيسية الضعيفة أو غير المقيمة مع الإشارة إلى مثيل فئة (مثل self) أو متغير تمت تهيئته ببعض القيمة (مثل delegate = self.delegate!). تتم كتابة هذه الأزواج داخل زوج من الأقواس المربعة ، مفصولة بفواصل.

ضع قائمة الالتقاط قبل قائمة معلمات الإغلاق ونوع الإرجاع إذا تم توفيرها:

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
}

تفسيرات إضافية


ضع [unowned self] قبل (text: String)... في غلقك. يدعى هذا قائمة التقاط وتضع تعليمات الملكية على الرموز التي تم التقاطها في الإغلاق.


EDITED: كما علق @ tim-vermeulen ، قال كريس Lattner على الجمعة 22 يناير 19:51:29 CST 2016 ، لا ينبغي استخدام هذه الخدعة على الذات ، لذا يرجى عدم استخدامه. تحقق من معلومات الإغلاقات التي لا تهرب من القائمة وإجابة قائمة الالتقاط منgbk.

بالنسبة لأولئك الذين يستخدمون [النفس الضعيف] في قائمة الالتقاط ، لاحظ أن النفس يمكن أن تكون معدومة ، لذا فإن أول شيء أقوم به هو التحقق من ذلك من خلال بيان الحارس

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

إذا كنت تتساءل ما هي علامات الاقتباس حول self هي خدعة مؤيدة لاستخدام الذات داخل الإغلاق دون الحاجة إلى تغيير الاسم إلى هذا ، ضعيف أو أي شيء.

ملاحظة: بما أنني أواجه بعض الأصوات الصاعدة ، أود أن أوصي بقراءة حالات الإغلاق غير الفاشلة . TL ؛ DR معظم الطرق تستدعي في نهاية الإغلاق الذي تم تمريره بالحجة ، إذا كان هذا هو الحال ، فيمكنك استخدامnoescape في حجة الإغلاق ويمكنك الرجوع إلى الذات ضمنيًا داخل الإغلاق.


تحرير: خدعة "النفس"

نظرًا لأنه لا ينصح باستخدام حل 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) }




retain-cycle