1
私はきれいなコードを書くのは難しいです。したがって、私は別のクラスファイルと拡張機能で自分のデータソースとdeletegateを保持したい。 M-V-Cスタイルに近づきたいしたがって、私のモデルはすべての私のコントローラクラスとビュークラスから分離されています。しかし、pickerViewオブジェクトに値を設定する際に問題があります。ここにコードがあります。
//私の代理人とデータソース 輸入財団 輸入のUIKit
class MyPickerView: NSObject{
var data = PickerViewData.getData()
}
extension MyPickerView: UIPickerViewDataSource{
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return 1
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return self.data.count
}
}
extension MyPickerView: UIPickerViewDelegate{
func pickerView(_ pickerView: UIPickerView, rowHeightForComponent
component: Int) -> CGFloat {
return 100
}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int,
forComponent component: Int, reusing view: UIView?) -> UIView {
let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
let dayLbl = UILabel(frame: CGRect(x: 0, y: 10, width: 100, height: 15))
let priceLbl = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
let petLbl = UILabel(frame: CGRect(x: 0, y: 78, width: 100, height: 15))
dayLbl.text = data[row].dayName
priceLbl.text = String(data[row].price)
petLbl.text = data[row].petName
dayLbl.textAlignment = .center
priceLbl.textAlignment = .center
petLbl.textAlignment = .center
view.addSubview(dayLbl)
view.addSubview(priceLbl)
view.addSubview(petLbl)
return view
}
}
//私のモデル
import Foundation
struct PickerViewModel{
var dayName:String!
var price:Double!
var petName:String!
init(dayName:String,price:Double,petName:String) {
self.dayName = dayName
self.price = price
self.petName = petName
}
}
struct PickerViewData {
static func getData() -> [PickerViewModel]{
let m = PickerViewModel(dayName: "Pazartesi", price: 32.3,
petName: "Köpek")
let p = PickerViewModel(dayName: "Salı", price: 32.3, petName:
"Kuş")
let z = PickerViewModel(dayName: "Çarşamba", price: 32.3,
petName: "Kedi")
let t = PickerViewModel(dayName: "Perşembe", price: 32.3,
petName: "Domuz")
let k = PickerViewModel(dayName: "Cuma", price: 32.3, petName:
"Kanarya")
return [m,p,z,t,k]
}
}
//マイコントローラー
import UIKit
class FirstVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .white
let pickerView = UIPickerView(frame: CGRect(x: 100, y: 100,
width: 200, height: 500))
let deldat = MyPickerView()
pickerView.delegate = deldat
pickerView.dataSource = deldat
self.view.addSubview(pickerView)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
あなたは正しいです!私は、データソースとデリゲートの弱点についての詳細を見落としました。さらに、私はデータソースを使用せず、インスタンスをローカルvarとして委譲しません。私は弱いキーワードはメモリのパフォーマンスに関するものなので、データソースとデリゲート変数が弱いと宣言されている理由を説明します。 ありがとうございます –
「弱い」と宣言すると、保持サイクルを防ぐことができます。あなたのView Controllerは(view'プロパティを使って)ピッカービューへの強い参照を保持します。データソース/デリゲートが弱い場合、ピッカービューは強い参照をビューコントローラに戻しています。これは、ビューコントローラが他の方法で解放されていれば(つまり、それを使用していたものは他にはありません)、特に、delegate/datasourceを ' nil'。デリゲート/データソースを弱くすることによって、これは発生しません。 – Paulw11
あなたの説明は完璧で、私は正しく理解しています。メモリリークの問題は、iPhoneにもたくさんのメモリが搭載されていなくても重要な問題です。だからdidReceiveMemoryWarning関数呼び出しに直面しないために、私は非常にメモリの種類のキーワードを使用することに注意します。 私はあなたをもっと邪魔していると感じますが、もう1つの最後の質問です。 なぜ、viewDidLoadが終了したときにローカルpickerViewインスタンスが解放されないのですか?それでも解放されてもピッカービューとやりとりしていますか? 私はアイデアを持っています、おそらくaddsubviewメソッドは私のpickerViewのコピーを保持しますか? –