2017-06-26 4 views
1

釘、UIPickerViewが入力されていません

私はきれいなコードを書くのは難しいです。したがって、私は別のクラスファイルと拡張機能で自分のデータソースと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. 
}  

} 

答えて

3

ピッカービューのdataSourcedelegateプロパティはweakと宣言されています。つまり、MyPickerViewインスタンスは保持されません。インスタンスはローカル変数であるため、viewDidLoadが終了するとすぐに解放されます。

あなたはそれがあなたのビューコントローラの寿命のために保持されるように、インスタンスのプロパティであなたのMyPickerViewインスタンスを保持する必要があります。

import UIKit 

class FirstVC: UIViewController { 

    private var deldat: MyPickerView! 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     self.view.backgroundColor = .white 
     let pickerView = UIPickerView(frame: CGRect(x: 100, y: 100, 
width: 200, height: 500)) 
     self.deldat = MyPickerView() 
     pickerView.delegate = deldat 
     pickerView.dataSource = deldat 
     self.view.addSubview(pickerView) 
    } 
} 
+0

あなたは正しいです!私は、データソースとデリゲートの弱点についての詳細を見落としました。さらに、私はデータソースを使用せず、インスタンスをローカルvarとして委譲しません。私は弱いキーワードはメモリのパフォーマンスに関するものなので、データソースとデリゲート変数が弱いと宣言されている理由を説明します。 ありがとうございます –

+1

「弱い」と宣言すると、保持サイクルを防ぐことができます。あなたのView Controllerは(view'プロパティを使って)ピッカービューへの強い参照を保持します。データソース/デリゲートが弱い場合、ピッカービューは強い参照をビューコントローラに戻しています。これは、ビューコントローラが他の方法で解放されていれば(つまり、それを使用していたものは他にはありません)、特に、delegate/datasourceを ' nil'。デリゲート/データソースを弱くすることによって、これは発生しません。 – Paulw11

+0

あなたの説明は完璧で、私は正しく理解しています。メモリリークの問題は、iPhoneにもたくさんのメモリが搭載されていなくても重要な問題です。だからdidReceiveMemoryWarning関数呼び出しに直面しないために、私は非常にメモリの種類のキーワードを使用することに注意します。 私はあなたをもっと邪魔していると感じますが、もう1つの最後の質問です。 なぜ、viewDidLoadが終了したときにローカルpickerViewインスタンスが解放されないのですか?それでも解放されてもピッカービューとやりとりしていますか? 私はアイデアを持っています、おそらくaddsubviewメソッドは私のpickerViewのコピーを保持しますか? –

関連する問題