彻底搞懂import "" 和 import <>
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了彻底搞懂import "" 和 import <>相关的知识,希望对你有一定的参考价值。
参考技术A我们新建一个项目,再创建一个类文件比如叫FooView,此时我们要在其它地方用到FooView的时候,我们一般这样
当我使用cocoapod安装第三方库,比如安装了Masonry,那么在用到Masonry的时候,一般我都会
为什么不用 "",因为我发现用""编译器并不会给出提示,所以我一直以为只能用<>,但是在我做过的几个项目中,我其实并没有用到 <>,而是一直都用的 "",曾经也很奇怪为什么会不一样,但之前也只是想想,可能是项目设置里面加了什么东西,也没有仔细深入了解。(PS:这种精神还是不可取的)
所以就会有这样一个思维:正常情况下,自己新建的文件用"",而通过cocoapod安装或者引用系统库文件,用<>
在Stack Overflow上有一个回答较高的解释:
所以当我们用<>引用我们新建的文件的时候,就会有这样一个提示:
在Xcode项目 - Build Settings 下搜索:search path
我们会看到有一个 Use Header Maps 开关,默认是打开的。这个意思是:开启这个开关后,在本地会根据当前目录生成一份文件名和相对路径的映射,依靠这个映射,我们可以直接import工程里的文件,不需要依靠header search path。
我们在管理项目的时候,一般都会把文件放在各个模块下面,模块以各个文件夹区分,在Xcode中创建文件夹会有两种方式,一种是虚拟文件夹(文件还是在项目根目录下),一种是真实文件夹。我之前一直觉得他们就是文件在不在一起的区别,当我关掉 Use Header Maps 这个选项的时候,这两种文件夹在这里又表现出了不一致。
我一开始是用New Group With Folder创建的真实文件夹
EventViewController是BaseViewController的子类,在头文件中引用了BaseViewController。
当我关掉Use Headers Maps选项的时候,就会报以下错误:
相对路径找不到BaseViewController,这时候EventViewController是在Event文件夹下,BaseViewController是在Base文件夹下,由于关闭了Header Maps,所以无法直接引用。
但是当我用虚拟文件夹管理文件的时候,由于他们都是在根目录下,所以通过相对路径引用是完全没有问题的,即使关闭了Use Headers Maps选项。
这时候我们就涉及到 Header Search Paths 和 User Header Search Paths 。两者都是提供search path,区别在于一个指明是用户的。并且如果编译器不支持user headers概念,会从header search paths中去寻找。并且看上面有一个 Always Search User Paths ,但是已经被Deprecated。查阅资料知道
我们现在要让编译器知道这个文件在哪里,所以要在search paths里面添加引用文件所在的文件夹。
在Header Search Paths里添加的话,无论import “” 还是 import <>都是没有问题的,在User Header Search Paths里添加,只能使用import “”
看下面的三种方式
思考一下这三种方式是否都正确?
.
.
.
答案是:都正确。
之前一直困惑用哪种方式,又好像哪种方式都正确。这次直接看 search paths下面,发现
cocopod在install的时候,会将第三方库的framework路径添加到Header Search Paths下,所以我们可以直接import,也可以import它的模块下的文件
如果按照Xcode默认配置的话,自己新建的文件直接import “”使用,cocoapod安装的第三方库使用import “”、import <>都可以使用。如果关闭Use Header Maps,文件不在根目录下的话,需要手动添加路径到search paths中,添加到User Header Search Paths只能通过import ”“使用,添加到Header Search Paths两种方式都可以。
Docker_03_彻底搞懂Dockerfile文件
文章目录
- 一、前言
- 二、Dockerfile基本命令
- 2.1 FROM (导入基础镜像,几乎是必须的,就像是java程序中的import导入)
- 2.2 RUN (在镜像内部执行一些命令,类似java程序中的main函数)
- 2.3 COPY 和 ADD (都是类似 linux cp 命令,放在一起学习)
- 2.4 WORKDIR(类似 linux 中 mkdir xxx && cd xxx 命令)
- 2.5 ENV (环境变量,类似springboot工程的中的环境变量)
- 2.6 VOLUME (挂载目录,磁盘操作) 和 EXPOSE (暴露端口,网络操作)
- 2.7 LABEL (给生成的镜像打上标签)
- 2.8 CMD 和 ENTRYPOINT (类似,放在一起学习)
- 2.9 Dockerfile常用命令小结
- 三、看懂一个Dockerfile
- 四、实践:jar -> image -> container
- 五、尾声
一、前言
二、Dockerfile基本命令
2.1 FROM (导入基础镜像,几乎是必须的,就像是java程序中的import导入)
FROM ubuntu:14.04
指定基础镜像,比如FROM ubuntu:14.04
2.2 RUN (在镜像内部执行一些命令,类似java程序中的main函数)
RUN groupadd -r mysql && useradd -r -g mysql mysql
在镜像内部执行一些命令,比如安装软件,配置环境等,换行可以使用""
2.3 COPY 和 ADD (都是类似 linux cp 命令,放在一起学习)
COPY docker-entrypoint.sh /usr/local/bin/
将主机的文件复制到镜像内,如果目录不存在,会自动创建所需要的目录,注意只是复制,不会提取和
解压,类似于 linux 上的 cp 命令,对文件或目录执行 复制 操作
ADD application.yml /etc/itcrazy2016/
更多的是将主机的文件复制到目录内,最后这个文件也被打到 image 镜像里面,用COPY也可以实现这个功能,但是ADD会对压缩文件提取和解压
2.4 WORKDIR(类似 linux 中 mkdir xxx && cd xxx 命令)
指定镜像的工作目录,之后的命令都是基于此目录工作(若不存在则创建),类似于是 xshell 中的 mkdir && cd 命令
WORKDIR /usr/local # 表示从根目录出发 mkdir /usr/local && cd /usr/local
WORKDIR tomcat # 表示从当前目录 (/usr/local) 出发,mkdir tomcat && cd tomcat
RUN touch test.txt
会在/usr/local/tomcat下创建test.txt文件
WORKDIR /root
ADD app.yml test/
会在/root/test下多出一个app.yml文件
2.5 ENV (环境变量,类似springboot工程的中的环境变量)
ENV MYSQL_MAJOR 5.7
设置变量的值,ENV MYSQL_MAJOR 5.7,可以通过docker run --e key=value修改,后面可以直接使
用$MYSQL_MAJOR
2.6 VOLUME (挂载目录,磁盘操作) 和 EXPOSE (暴露端口,网络操作)
VOLUME /var/lib/mysql
指定数据的挂在目录
EXPOSE 3306
指定镜像要暴露的端口,启动镜像时,可以使用-p将该端口映射给宿主机
2.7 LABEL (给生成的镜像打上标签)
LABEL email="itcrazy2016@163.com"
LABEL name="itcrazy2016"
设置镜像标签
2.8 CMD 和 ENTRYPOINT (类似,放在一起学习)
好了,Dockerfile所有的准备工作都完成了,现在要启动这个Dockerfile,将 .jar 变成一个 image 镜像。Dockerfile中的ENTRYPOINT指令和CMD指令都可以设置容器启动时要执行的命令,但用途是有略微不同的。这两个类似于 xshell 对于可执行脚本(linux上白色是文件,绿色是可执行文件,蓝色是目录),./aa.sh 执行。
容器启动的时候默认会执行的命令,若有多个CMD命令,则最后一个生效
CMD ["mysqld"] 或CMD mysqld
和CMD的使用类似
ENTRYPOINT ["docker-entrypoint.sh"]
和CMD的不同,docker run执行时,会覆盖CMD的命令,而ENTRYPOINT不会
ENTRYPOINT指令和CMD指令虽然是在Dockerfile中定义,但是在构建镜像的时候并不会被执行,只有在执行docker run命令启动容器时才会起作用。
1、在Dockerfile中,只能有一个ENTRYPOINT指令,如果有多个ENTRYPOINT指令则以最后一个为准。
2、在Dockerfile中,只能有一个CMD指令,如果有多个CMD指令则以最后一个为准。
3、在Dockerfile中,ENTRYPOINT指令或CMD指令,至少必有其一。
对于每个Dockerfile文件,存在三种情况:
情况1:Dockerfile中最后只有一条ENTRYPOINT指令;
情况2:Dockerfile中最后只有一条CMD指令;
情况2:Dockerfile中最后有一条ENTRYPOINT指令和CMD指令。
参考资料:https://blog.csdn.net/u010797364/article/details/120543245
参考资料:https://blog.csdn.net/qq_45300786/article/details/103947527
2.9 Dockerfile常用命令小结
开始,写一个Dockerfile文件的时候:
第一,先一个 FORM 命令,表示导入基础镜像,几乎是必须的,就像是java程序中的import导入;
第二,开始在 Dockerfile 中执行 RUN (在镜像内部执行一些命令,类似xshell程序中的main函数),执行 COPY 和 ADD (都是类似 linux cp 命令,放在一起学习),执行 WORKDIR(类似 linux 中 mkdir xxx && cd xxx 命令);
第三,需要的环境环境 ENV (环境变量,类似springboot工程的中的环境变量)
第四,VOLUME (挂载目录,磁盘操作) 和 EXPOSE (暴露端口,网络操作)
第五,LABEL 给需要生成的image镜像打好标签
最后,镜像完成之后,执行 CMD 和 ENTRYPOINT。
三、看懂一个Dockerfile
3.1 在Github上找到一个Dockerfile文件
3.2 阅读一个官方的Dockerfile
https://github.com/docker-library/mysql/blob/master/5.7/Dockerfile.debian
#
# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh"
#
# PLEASE DO NOT EDIT IT DIRECTLY.
#
FROM debian:buster-slim
# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
RUN groupadd -r mysql && useradd -r -g mysql mysql
RUN apt-get update && apt-get install -y --no-install-recommends gnupg dirmngr && rm -rf /var/lib/apt/lists/*
# add gosu for easy step-down from root
# https://github.com/tianon/gosu/releases
ENV GOSU_VERSION 1.14
RUN set -eux; \\
savedAptMark="$(apt-mark showmanual)"; \\
apt-get update; \\
apt-get install -y --no-install-recommends ca-certificates wget; \\
rm -rf /var/lib/apt/lists/*; \\
dpkgArch="$(dpkg --print-architecture | awk -F- ' print $NF ')"; \\
wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \\
wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \\
export GNUPGHOME="$(mktemp -d)"; \\
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \\
gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \\
gpgconf --kill all; \\
rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \\
apt-mark auto '.*' > /dev/null; \\
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \\
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \\
chmod +x /usr/local/bin/gosu; \\
gosu --version; \\
gosu nobody true
RUN mkdir /docker-entrypoint-initdb.d
RUN set -eux; \\
apt-get update; \\
apt-get install -y --no-install-recommends \\
bzip2 \\
openssl \\
# FATAL ERROR: please install the following Perl modules before executing /usr/local/mysql/scripts/mysql_install_db:
# File::Basename
# File::Copy
# Sys::Hostname
# Data::Dumper
perl \\
xz-utils \\
zstd \\
; \\
rm -rf /var/lib/apt/lists/*
RUN set -eux; \\
key='859BE8D7C586F538430B19C2467B942D3A79BD29'; \\
export GNUPGHOME="$(mktemp -d)"; \\
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \\
mkdir -p /etc/apt/keyrings; \\
gpg --batch --export "$key" > /etc/apt/keyrings/mysql.gpg; \\
gpgconf --kill all; \\
rm -rf "$GNUPGHOME"
ENV MYSQL_MAJOR 5.7
ENV MYSQL_VERSION 5.7.39-1debian10
RUN echo 'deb [ signed-by=/etc/apt/keyrings/mysql.gpg ] http://repo.mysql.com/apt/debian/ buster mysql-5.7' > /etc/apt/sources.list.d/mysql.list
# the "/var/lib/mysql" stuff here is because the mysql-server postinst doesn't have an explicit way to disable the mysql_install_db codepath besides having a database already "configured" (ie, stuff in /var/lib/mysql/mysql)
# also, we set debconf keys to make APT a little quieter
RUN \\
echo mysql-community-server mysql-community-server/data-dir select ''; \\
echo mysql-community-server mysql-community-server/root-pass password ''; \\
echo mysql-community-server mysql-community-server/re-root-pass password ''; \\
echo mysql-community-server mysql-community-server/remove-test-db select false; \\
| debconf-set-selections \\
&& apt-get update \\
&& apt-get install -y \\
mysql-server="$MYSQL_VERSION" \\
# comment out a few problematic configuration values
&& find /etc/mysql/ -name '*.cnf' -print0 \\
| xargs -0 grep -lZE '^(bind-address|log)' \\
| xargs -rt -0 sed -Ei 's/^(bind-address|log)/#&/' \\
# don't reverse lookup hostnames, they are usually another container
&& echo '[mysqld]\\nskip-host-cache\\nskip-name-resolve' > /etc/mysql/conf.d/docker.cnf \\
&& rm -rf /var/lib/apt/lists/* \\
&& rm -rf /var/lib/mysql && mkdir -p /var/lib/mysql /var/run/mysqld \\
&& chown -R mysql:mysql /var/lib/mysql /var/run/mysqld \\
# ensure that /var/run/mysqld (used for socket and lock files) is writable regardless of the UID our mysqld instance ends up having at runtime
&& chmod 1777 /var/run/mysqld /var/lib/mysql
VOLUME /var/lib/mysql
COPY docker-entrypoint.sh /usr/local/bin/
RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 3306 33060
CMD ["mysqld"]
四、实践:jar -> image -> container
4.1 jar -> image -> container
(1)创建一个Spring Boot项目
(2)写一个controller
@RestController
public class DockerController
@GetMapping("/dockerfile")
@ResponseBody
String dockerfile()
return "hello docker";
(3)mvn clean package打成一个jar包 在target下找到"dockerfiledemo-0.0.1-SNAPSHOT.jar"
(4)在docker环境中新建一个目录"first-dockerfile"
(5)上传"dockerfiledemo-0.0.1-SNAPSHOT.jar"到该目录下,并且在此目录创建Dockerfile
(6)创建Dockerfile文件,编写内容
FROM openjdk:8
MAINTAINER mao
LABEL name="dockerfile-demo" version="1.0" author="mao"
COPY dockerfile-demo-0.0.1-SNAPSHOT.jar dockerfile-image.jar
CMD ["java","-jar","dockerfile-image.jar"]
(7)基于Dockerfile构建镜像
docker build -t test-docker-image .
(8)基于image创建container
docker run -d --name user01 -p 6666:8080 test-docker-image
(9)查看启动日志
docker logs user01
(10)宿主机上访问
curl localhost:6666/dockerfile
hello docker
(11)还可以再次启动一个
docker run -d --name user02 -p 8081:8080 test-docker-image
注意1:mvn clean package 将 jar变为package
注意2:宿主机都是当前的centos机器
4.2 jar -> image -> container
五、尾声
彻底搞懂Dockerfile文件,完成了。
以上是关于彻底搞懂import "" 和 import <>的主要内容,如果未能解决你的问题,请参考以下文章
彻底搞懂Python 中的 import 与 from import
彻底搞懂Python 中的 import 与 from import
彻底搞懂Python 中的 import 与 from import