2017-08-07 5 views
3

viewdidload()はUIViewControllerオブジェクトのそのインスタンスのライフサイクルで一度呼び出されるだけなので、setBackgroundColor()は一度だけ呼び出される関数であり、不必要に読み込まれるため、この例は「悪い習慣」です。 viewdidload()の内部に完全に(定義され呼び出されて)本当に存在するはずのクラス全体のメモリに格納されますか?効率性の面では、setBackgroundColor()が定義されて呼び出される場所は関係ありませんか?viewdidload()の中で関数を定義することは、それらを外側に定義するよりも多くのメモリを節約しますか?

class MasterViewController: UIViewController { 

    func setBackgroundColor() { 
     self.view.backgroundColor = UIColor.green 
    } 

    // Do any additional setup after loading the view, typically from a nib. 
    override func viewDidLoad() { 
     super.viewDidLoad() 

     setBackgroundColor() 

    } 

    // Dispose of any resources that can be recreated. 
    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 

} 

答えて

2

これは、メモリ使用量の場合ではありません、それは効率的にビューをロードする問題です。

UIViewControllerコントロールがビューを制御します。しかし、ビューはView Controllerと同時に作成されるわけではありません。

viewDidLoadで背景色を実際に設定すると、そのビューが呼び出されると、ビューコントローラーのライフサイクルの都合のよい時点でビューが作成されている(必ずしも表示されない)ためです。ビューコントローラを作成してからsetBackgroundColorメソッドを呼び出した場合、コールのself.view部分がまだ作成されていない場合は、すぐにビューが作成されます。

ビューコントローラのプレゼンテーションなどの特定のメソッドでは、ビューをすぐにロードせずにUIを応答可能に保ちながら、作成メソッドをできるだけ早く戻すことができます。

UIViewControllerにはビューがメモリにロードされているかどうかにかかわらずブールを返すが、ビューを読み込まないようにするためのパラメータはisViewLoadedです。

2

私はあなたのコードでメモリの懸念があるものは表示されません。マイクロ最適化は、ソフトウェア開発における最大の時間です。しかし、あなたが尋ねたので、viewDidLoadが1回だけ呼び出されます。 AppleのWork with View Controllers

viewDidLoad() -Calledビューコントローラのコンテンツビュー(そのビュー階層の最上位)を作成し、絵コンテからロードされます。 View Controllerのアウトレットは、このメソッドが呼び出されるまでに有効な値を持つことが保証されています。このメソッドを使用して、View Controllerに必要な追加設定を実行します。

通常、iOSはコンテンツビューが初めて作成されたときにviewDidLoad()を1回だけ呼び出します。ただし、コントローラが初めてインスタンス化されたときにコンテンツビューが作成されるとは限りません。その代わりに、システムまたはコードがコントローラのviewプロパティに初めてアクセスするときに遅延生成されます。

+0

ドキュメントでは、「このメソッドを使用してView Controllerに必要な追加設定を実行する」と言いますが、背景色を実際に「追加設定」に設定していますか?それはプライマリではなく、基本的なセットアップですか? funcは、viewdidload()の中にないと読み込まれません。これは、「追加設定」の文言が少し誤解を招くと思います。はい? –

+0

viewControllerはビューとは異なることに気づくことが重要です。 viewControllerの設定の一部であるビューの色を設定しています。 – toddg

3

メソッドにローカルな関数を作成すると、スコープは変更されますが、コンパイルされたコードの有効期間は変更されません。クラスのメソッドにも同じことがあります:少なくともバイナリコードは、この時点では個別に管理されません。あなたの関数の実行可能コードは比較的小さいので、これは大きな問題ではありません。関数定義ので、これは読みやすさを向上させ

override func viewDidLoad() { 
    super.viewDidLoad() 
    // Nested function definition 
    func setBackgroundColor() { 
     self.view.backgroundColor = UIColor.green 
    } 
    // Calling nested function 
    setBackgroundColor() 
} 

:ここで重要なもの

は、関数名は、他の方法がviewDidLoad内で定義されたものに関係のない、独自のsetBackgroundColor()関数を定義せ、その外側のスコープで表示されていないということですそれが使用されているところにあります。コードをリファクタリングしている人なら、setBackgroundColor以外の用途はviewDidLoadの範囲外になることはありませんので、メンテナンス性が向上します。

もちろん、これは単なる例です。ネストされた関数は、ここでは必要ありません - あなたは、このように、setBackgroundColor機能せず、それを書き換えることができます。

override func viewDidLoad() { 
    super.viewDidLoad() 
    self.view.backgroundColor = UIColor.green 
} 
2

私の推測では、効率の低下はより読みやすいコードを得ることに価値があると思います。実際には、コンパイラの最適化では、それをprivateとマークすると関数をインライン化することさえあります。これが間違いないかどうかを知るためにSwiftコンパイラ(LLVM)について十分に分かっていませんが、それは可能かもしれません。

Martin Fowlerはgreat article on function lengthを持っています。彼は、コードを分かりやすくするために1行に多くの機能があると述べています。

関数呼び出しのパフォーマンスコストを心配している人がいるため、短い関数が心配です。私が若いときには、時にはそれが原因だったが、これはまれです。コンパイラの最適化は、より簡単に機能する短い関数でよりよく機能します。今までのように、パフォーマンスの最適化に関する一般的なガイドラインは重要です。

ない機能のキャッシングについての彼のノートはスウィフトに適用するかどうかわからないが、彼はまた言う:

あなたはそれをやっている何を把握するために、コードのフラグメントを見に努力を費やす必要がある場合それを関数に展開し、その関数の名前に "what"を付ける必要があります。あなたがそれをもう一度読むと、関数の目的がすぐに飛び越します。

一般に、私は問題に気づかない限り最適化にあまり集中しません。 YAGNI

...コードが異なると、はいViewDidLoad()は1回だけ呼び出されます。

関連する問題