Swift リファクタリング忘備録 注意-読む価値はありません。!

デリゲート処理はweakで宣言しておかないと、メモリーリークを起こす可能性がある。

//変更前
protocol CommentDelegate {
    func commentOptionTapped(comment: Comment)
}
private var delegate: CommentDelegate


//変更後
protocol CommentDelegate: class {
    func commentOptionTapped(comment: Comment)
}

private weak var delegate: CommentDelegate

ポイント protocol はclass属性

アクセスするプロパティは weak で宣言

SWIFT awakeFromNib とinitWithCoderの違い 忘備録

initWithNibName:bundleとは

initWithNibName:bundle:はNSおよびUIViewControllerのメソッドです(CocoaではNSWindowController)。 nibは、実際には、-window(NSWindowController)または-loadView(NS / UIViewController)に応答して後でロードされます。 これは遅延読み込みです。 コントローラのウィンドウまたはビューが必要ない場合、そのnib先は読み込まれず、時間を節約できます。 View Controllerをインスタンス化するときにinitWithNibName:bundle:を送信するだけでよく、View-Controllerサブクラスでカスタムのインスタンス化動作を実装するときにのみオーバーライドする必要があります。 サブクラスがmyViewControllerやinitを定義してinitWithNibName:bundle:をハードコードされた値で送信するなどの便利なコンストラクターのみを追加する場合は、initWithNibName:bundle:もオーバーライドする必要はありません。

initWithCoder

initWithCoder:は、アーカイブをアーカイブ解除するためにアーカイブからアーカイブ解除されたすべてのオブジェクトに送信されるメッセージです。オブジェクトは、アーカイブからすべてのivar値とプロパティ値を読み込むことにより、このメッセージに応答します。

nib先はアーカイブなので、initWithCoder:はnib先のすべての実際のオブジェクトに送信されます。そのような場合、通常、nib先から何も抽出する必要はありません。 Appleの実装は、通常のものをすべて処理します。アーカイブから最初に配置するカスタムプロパティ(encodeWithCoder:内)のみを抽出する必要があるため、カスタムプロパティをnibでエンコードできないため、nibsからデコードする必要はありません。 。

「File's Owner」、「First Responder」、およびその他の特定のオブジェクトは偽のオブジェクトであることに注意してください。それらは実際にはnib先には存在しません。 Xcodeのnibエディターは、これらを負のID番号で表示します。

通常、initWithCoder:をオーバーライドする必要はありません。そうするときは、オブジェクトがどのようにインスタンス化されたか(コードまたはnibからアーカイブ解除された)に関係なく、最初から特定のプロパティ(可変配列またはセットなど)を埋める必要があるオブジェクトがある場合です。

initWithCoder:と1つ以上の非デコード対応物の両方を定義すると、それらの間にコード​​のリスクが高くなります。通常、commonInitメソッドを定義し、そこに通常のものを配置し、両方のinit [WithCoder:]メソッドに[self commonInit]を送信させます(注:スーパーではありません!)。

awakeFromNib

awakeFromNibは、nib内のすべてのオブジェクトが完全にロードされた後にnib内のすべてのオブジェクトに送信されるメッセージであり、そのnib内のすべてのアウトレット接続を再接続します。

いくつかの注意事項があります: これは、すべてのアウトレットが満たされることを意味するものではありません。オブジェクトをロードしたnib先で接続しないものは、そのロードで満たされません。これらのivar / propertiesは空のままです。オブジェクトが別のnib先のファイルの所有者である場合、そのnib先に設定されているアウトレット接続を完了するために、そのnib先をロードする必要があります。同じことは、同じFile's Ownerで2つ以上のnib先をロードする場合にも当てはまります。 2つの別々のnib先でオブジェクトを作成することはできません。両方のnib先をロードすると、2つのオブジェクトが生成されます。 (シングルトンの場合は、キャットファイトが予想されます。) 特定のアウトレットが接続されているnib先からオブジェクトをロードし、それがファイルの所有者であり、同じアウトレットが他の何かに接続されている別のnib先をロードすると、新しい接続が最初の接続をオーバーライドします。同じことは、同じFile's Ownerで2つ以上のnib先をロードする場合にも当てはまります。 Cocoa Touchでは、これは冗長であり、混乱を招く可能性があります(「私のアウトレットが[最初のnib先のオブジェクト]に接続されていないのはなぜですか?」) Cocoaでは、最初のオブジェクトは必ずしも解放されないため、リークが発生する可能性があります。 (Cocoa TouchはKVCを使用してアウトレット接続を埋めますが、Cocoaは使用しませんが、アクセサーを定義する場合はアクセサーを使用します。) Cocoaでは、awakeFromNibはnib内のすべてのオブジェクトとFile's Ownerに送信されます。 Cocoa Touchでは、ファイルの所有者には送信されません。

参照元

Cocoa (API): What is the difference between initWithCoder:, initWithNibName:, and awakeFromNib? - Quora

Django 便利なリファレンス集 ver2.2.0途中 読まないこと

モデルの関連について

Model field reference | Django documentation | Django

モデルの型

ImageField imageを格納するとき

IntegerField Int型

CharField 文字列

https://docs.djangoproject.com/en/2.2/ref/models/fields/#imagefield

Djangoアプリ Heroku デプロイ

初めからの手順

git のインストール

gitforwindows.org

Heroku CLIのインストール

herokuにログインしたり、デプロイするためのコマンドを利用できる devcenter.heroku.com

djangoをherokuにデプロイするには以下の3つが必要

runtime.txt => Pythonのバージョンを記載

requirements.txt

setup.py

Pipfile

runtimte.txt

python-3.6.0

必要なモジュールのインストール

python3 -m pip install gunicorn

gunicornとは何かというとWSGI HTTPサーバーのこと

Gunicornの「Green Unicorn」は、UNIX用のPython WSGI HTTPサーバーです。 これは、RubyのUnicornプロジェクトから移植されたpre-forkワーカーモデルです。 Gunicornサーバーは、さまざまなWebフレームワークと幅広く互換性があり、シンプルに実装され、サーバーリソースの使用量が少なく、かなり高速です。

requirements.txt ファイルの作成 herokuこのファイルを見て、モジュールインストールする

pip freeze でインストールされているパッケージが表示される。それをそのまま記載する。

pip freeze

//===
asgiref==3.2.7
Django==3.0.6
gunicorn==20.0.4
Pillow==7.1.2
pytz==2020.1
sqlparse==0.3.1

で表示されたものをrequirement.txtに記載する

Prockfile の作成

どのWEBサーバーを利用するか、どんなコマンドを実行するか記載してあげる

web: gunicorn "プロジェクト名".wsgi --log-file -
release: python manage.py migrate

==========今日はここまで

pip install whitenoise

.gitignore ファイルの作成

不要なログ・ファイルなどをuploadしないため コピペして.gitignoreファイルに貼り付ける

//MACの場合追記する
.DS_Store

github.com

git init
git add .
git status //チェックする
git commit -m "initial"

heroku

heroku create xxxxapp_name

//これでdeployできる
git push heroku master

デプロイにはSTATIC_ROOTの定義が必要

setting.py

STATIC_URL = '/static/'  //アプリ内のフォルダ名
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

修正したら git push heroku master を繰り返す

logの見方

//logを見れば問題がわかる
heroku logs --tail

Procfile ファイルの作成

拡張子はつけない プロセスを記載する。

//webはプロセス名 
//gunicornはコマンド
//xxxdjango_projectはsetting.pyに登録してるアプリ名
//wsgi  Web Service Gateway Interface 
web: gunicorn xxxxdjango_project_name.wsgi

//他のバックグラウンドのワーカーなども登録可能

ALLOWED_HOSTの追加

Djangoのセキュリティーの為

セキュリティーキーの作成 python3.6以上が必要

operation error no such table: xxx_xxx

herokuにDBがないと言われている

heroku上のDBの確認

//pg はポストグレスの略 herokuではDBはポストグレス
heroku pg

db上の設定をしてくれるライブラリ

インストールするだけで whitenoiseやDB-urlなどを設定してくれる

pip install django-heroku

setting.py

import django_heroku

Django エラーModuleNotFoundError: No module named 'virtualenvwrapper'

こんなエラーがでた。 環境 MAC OS 10.15.2 python 3.5 Django 2.2

ModuleNotFoundError: No module named 'virtualenvwrapper'

Djangoで開発中の、デバッグ中に発生する

virtualenvwrapperとは

公式サイト virtualenvwrapper.readthedocs.io

virtualenvwrapper の特徴

すべての virtualenv 環境を一元管理できる
便利な各種コマンド
環境の切り替えがコマンドひとつでタブによるコマンド補完
カスタマイズ可能なフック
拡張機能も自由に開発可

便利な開発環境を提供してくれます。 これは従来

pip install virtualenvwrapper

でインストールできていた。

.bash_profile

//pyenv関係
export PATH="$HOME/.pyenv/shims:$PATH"
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"

//システム標準のpython
export PATH=$PATH:/Users/imac2/Library/Python/3.7/bin
alias python="python3"

export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3

brew では、pyenv がインストールされている

$ brew list
autoconf        libimobiledevice    openssl@1.1
automake        libplist        pkg-config
aws-elasticbeanstalk    libtasn1        pyenv //ここにある
carthage        libtool         python //pythonも

pyenvとは

pythonのバージョンを同一PC内で使い分けることが可能。

pyenvで利用される shimコマンドとは

shimコマンドは、 $HOME/.pyenv/shims/ に配置されるコマンド群

  • 環境のpythonのバージョンを調べて、そのバージョンを利用する
  • .python-version ファイルがあればそのpythonのバージョンを利用する

これにより、環境を構築したフォルダに .python-version があれば、そのバージョンを開発に利用できる

virtualenvの構成

virtualenvのコマンドで、任意のディレクトリにPython の実行環境を作成できる pythonコマンドは、自身の親ディレクトリにある include,libディレクトリを参照する。 現在これを利用していた。 f:id:happy_teeth_ago:20200103104601p:plain

参考にさせていただきました。

stackoverflow.com

この記事によると

最近のHomebrewの更新後も同じ問題が発生しました。

過去には、ほとんどの人がpip install virtualenvwrapperをシステムサイトパッケージに実行していましたが、それは機能していました。

Homebrewは、

1)システムpythonをシャドウイングしなくなり、

2)pipをpip2 / pip3にシンボリックリンクしなくなった.

上記理由により、このワークフローが中断されました。

ほとんどのユーザーは、pipが見つからないときにこれを認識し、pip2 / pip3を使用しようとします。 しかし、virtualenvwrapperはpython2 / python3ではなくpython2 / python3にインストールされるため、pip2 / pip3を使用すると問題が発生します。 そのため、virtualenvwrapperを実行してpythonを呼び出すと、システムpythonのサイトパッケージでvirtualenvwrapper / virtualenv pythonパッケージが見つかりません。のエラーが発生する。

VIRTUALENVWRAPPER_PYTHONを明示的に設定することは最もクリーンな修正である。 ふむふむ

仮想環境を利用するときのactivateは何をしているのか?

//activateより
PATH="$VIRTUAL_ENV/bin:$PATH"
export PATH
どこにpipでインストールされているのか pip show コマンドで調べる
//これでpipのインストール場所を調査できる
$ pip show virtualenvwrapper

Name: virtualenvwrapper
Version: 4.8.4
Summary: Enhancements to virtualenv
Home-page: https://virtualenvwrapper.readthedocs.io/
Author: Doug Hellmann
Author-email: doug@doughellmann.com
License: MIT

//これはおかしい
Location: /Users/imac2/.pyenv/versions/3.5.2/lib/python3.5/site-packages
Requires: virtualenv, virtualenv-clone, stevedore

.pyenvに入っている!!

現在の開発の仮想環境にインストールされていない。 解決方法は2つ

1-今の環境を指定してVIRTUALENVWRAPPERをpipインストールする。

-t オプションでインストール可能

2-VIRTUALENVWRAPPER_PYTHONのpathを設定してあげる

.bashrc

bashrcはbashを起動するたびに毎回呼ばれる。 シェル関数を定義したりする。 .bash_profileは起動時1回しか呼ばれない。

export WORKON_HOME=$HOME/.virtualenvs
source /Users/hideyasuimac2/.pyenv/shims/virtualenv/virtualenvwrapper.sh

参考にさせていただきました。

qiita.com

Django エラー return Database.Cursor.execute(self, query, params) django.db.utils.OperationalError: no such table:

エラーメッセージ

  return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: no such table: xxxxxx.app

マイグレーションをしていないだけ

解決

$ python manage.py makemigrations

$ python manage.py migrate

$ python manage.py makemigrations
Migrations for 'xxxxapp':
  xxxxapp/migrations/0001_initial.py
    - Create model Restaurant


$ python manage.py migrate

Operations to perform:
  Apply all migrations: admin, auth, contenttypes, xxxxxapp, oauth2_provider, sessions, social_django
Running migrations:
  Applying xxxxxapp.0001_initial... OK