c-notes

image

间接 标准 统一 机制 策略

iTerm 的配置

  1. 将iTerm移到应用程序

    进入配置文件

1
$ cd iterm$zsh/.oh my zsh/templates
  1. ls 查看当前目录下的所有文件

    拷贝当前目录下的文件 zshrc.zsh-template 到~/.zshrc 下

1
$ cp zshrc.zsh-template
  1. 退出iterm,重启即可
1
$ q

VI编辑器中的基本命令

VI编辑器中的基本内部命令

在终端使用 vimtutor 命令可以查看VI编辑器中的基本命令

  1. 复制命令

    复制单个字符: y

    复制一个单词: yw

    复制所选中的一行: yy

  2. 移动命令
    移动光标到行首: ^

    向前移动一个单词: b

    向后移动一个单词: w

    向下翻一页: ctrl + f

    向上翻一页: ctrl + b

  3. d + ^ 删除光标所在位置到行首的所有字符

  4. d + $ 删除光标所在位置到行尾的所有字符
VI编辑器中的基本外部命令
  1. 删除命令

     * rm [filename] 删除基本文件
     * rm -r [filename] 有提示的删除一个文件夹
     * rm -rf [filename] 强制删除文件夹,包括文件夹内的所有子文件夹以及自文件,且无提示 
      * rm \*~   (*为通配符),即删除所有以~结尾的文件
    
  2. 拷贝命令

     * 若file2文件家不存在,默认将file1 拷贝一分命名为file2 
     * 若file2时文件夹,默认将file1拷贝到文件夹file2下,且名字仍为file1 
     * file1 file2 不加路径的情况下,默认是把当前路径下的文件拷贝到当前路径下 
     * ile1 file2 表示为路径的形式,则是把指定路径下的file1 拷贝到指定路径下命名为file2,或是拷贝到制定路径下的file2文件夹下命名仍然是file1 
     * cp -r/R [file1][file2] 
     * 将文件夹1拷贝到文件夹2目录下 
    
  3. 重命名(移动命令)

    mv [file1][file2]

    • 若两文件在同一路径下且file2文件家不存在,默认将file1 重命名为file2
    • 若file2时文件夹,默认将file1移动到文件夹file2下,且名字仍为file1
      • file1 file2 不加路径的情况下,默认是把当前路径下的文件重命名为file2
    • file1 file2 表示为路径的形式,则是把指定路径下的file1 移动到指定路径下命名为file2,或是移动到指定路径下的file2文件夹下命名仍然是file1
  4. 其他命令

    • ls -a列出当前目录下的所有文件及文件夹,包括隐藏文件(以 “.” 开始的文件或文件夹)其中 . 和 ..两个文件夹表示是当前路径和上级路径
    • cd 切换路径
    • du -h [filename] 默认为查看当前路径下人类可读的文件的大小,追加filename,则是查看该文件夹下的人类可读的文件的大小
    • diff [file1][file2]比较两个文件内容是否相同,相同的话无显示结果;不同的话,则列出不同之处
    • file [file] 查看该文件的类型(如二进制类型,ASCII,English等)
    • !!调出上次使用的命令
      ! + 使用过的命令的首字母后第一个单词,调出最近使用过包含该字母或单词的命令
      ctrl + r 搜索使用过的命令
      ctrl + c 结束当前输入的命令,即不执行当前输入的命令
    • gcc 执行命令时 加-g 可进行调试 (l 列出函数的源代码,b 设置断点,r 运行程序,n 执行下一步,s 进入函数内部,p [var] 打印变量var的值 q 退出程序 ), 加 -save-temps 保留编译时生成的结果(即 .i, .s, .o 文件生成且被保留下来可供查看)
    • $?(echo $? 在屏幕上显示上次命令执行的结果,若执行成功则返回0,否则返回1;若上次执行是程序且执行成功则返回return 后的返回值)
      echo $HOME 显示当前的home路径
      echo $USER 显示当前的用户名
    • cat [filename] | head 查看文件的前十行内容

      注释方法

    • // 注释一行
    • 注释多行

      1. /*…*/
      2. #if 0

        #else

        #endif

        注释从 if 0 到else之间的多行,程序在编译,只编译else与endif之间的多行;若果把0换成非零值,则只

    • 头文件的保护

      #ifndef [宏名]

      #define [宏名]

      #endif

      在引用头文件时,如果未定义头文件内已定义过的内容,则定义;否则,不再重复定义

变量的作用范围

  1. 函数作用域 仅限在一个函数中使用
  2. 文件作用域 仅限在一个文件中使用
  3. 代码快作用域 受限与“ {}” 的限制
  4. 原型作用域 函数声明

变量的大小

  1. char c 语言标准规定为1字节
  2. int 一般为4字节 规定int的大小不超过long的大小,short的大小不超过int的大小
  3. 指针的大小与long的大小等于机器字长(即 32位os 其大小为4字节,64的os其大小为8字节),古可用sizeof(int)测试机器os时多少位的(sizeof只是一个操作符,并不是一个函数)。

数据类型

  • 整型:char short int long
  • 浮点型: float double
  • 指针
  • 聚合类型:数组,结构体,枚举类型
  • 派生类型:字符串,联合体

    赋值操作 值得注意点

  • 数组名是个地址,只能在初始化是对其赋值,在以后使用中,数组名是个地址常量,不能被作为左值对其赋值
  • 对字符数组初始化赋值为字符串字面常量,相当于把全局数据段的字符串复制到栈对字符数组分配的地址中去。
  • 指针是指针变量可以对其进行赋值运算
  • 结构体类型的变量可以作为左值对其进行赋值

分配内存问题

  • 在函数中定义变量,对其分配内存时不能太大
  • 可使用全局变量在全局数据段分配大内存
  • 可使用malloc(size)动态在堆中分配大内存,使用memset将申请的内存初始化。

字符串操作中段错误

  • 定义一个指向NULL地址的字符串指针
    NULL的ascii值为0,地址为0的内存不可以被访问,故对该地址进行写操作是没有权限的。
  • 在定义一个字符串数组时对其进行初始化为字符串字面常量
    对字符串数组定义并初始化为一个字符串字面常量时,字符数组首地址指向的是全局数据段的地址,对该段内存进行写操作是没有全县的。
  • 使用strcpy,strcat,strcmp,strcasecmp等字符串操作函数,将目标字符串读/写爆。应该使用strncpy,strncat,strncmp,strncasecmp等字符串操作函数防止读写越界。

文件操作常用函数

  1. 字符读写 fgetc(FILE *fp);
1
fputc(int c,FILE*fp);
  1. 按行读写 fgets(char str,size,FILE \fp);
1
fputs(char \*,size,FILE *fp);
  1. 数据块读写 fread(char *,size,number,FILE *fp);
1
fwrite(char \*, size,number,FILE \*fp);
  1. 格式化读写 fprintf(FILE *fp,format,…);
1
fsanf(FILE *fp,format,...);
三种缓冲机制
  • 行缓冲 缓冲区存储一行信息才进行输出 eg:stdout(标准输出)
  • 全缓冲 缓冲区存储满信息才进行输出
  • 无缓冲 缓冲区只要有信息存储进去就进行输出 eg:stderr(报错)
    改变文件指针位置
    • rewind(FILE *fp); 改变指针指向头文件
    • fseek(FILE *fp,int length,long where);(where 可取值为SEEK_SET SEEK_CUR SEEK_END) 改变指针位置从(文件头部,当前位置,文件尾部)移动length个字节的位置

image

git-base-operation

image

基本操作

创建一个裸仓库

git init --bare

初始化基本仓库

git init

配置作者信息

1
2
git config --global user.name "liufengxia"
git config --global usr.emil 1874962073@163.com

添加文件到暂存区(跟踪文件)

git add [filename]

git add * // 跟踪所有已跟踪过又修改的文件

移除文件

git rm [filename]

重命名一个文件

git mv [oldname] [newname]

提交暂存区

git commit -m "description information"// git commmit 只提交在暂存区的内容

git commit -a -m "description information"// 将跟踪过又修改的为放入暂存跟踪后直接提交,已放入暂存区的也直接一起提交

查看工作目录的状态

git status

查看提交历史记录

git log

查看文件改变

git diff //默认比较工作区下的文件与最近一次提交的不同

git diff -- stash//比较暂存区下的文件与最近一次提交的不同

撤销操作

撤销加入暂存区的操作

git reset -- [filename]

撤销修改的操作

git checkout -- [filename]

将本地的修改放进回收站

git stash

从回收站中恢复本地的修改

git stash apply

Tag操作

查看tag

git tag

创建tag

git tag -a tagname -m "tag description information"

显示tag信息

git show tagname

对之前的提交打tag

git tag -a tagname -m "tag description information" commit-num

分支操作

查看分支

// 默认查看本地分支

git branch

// 查看本地以及远端分支

git branch -a

// 查看远端分支

git branch -r

创建分支

git branch newbranchname

删除分支

git branch -d/D branchname

切换分支

git checkout branchname

创建分支并切换到新建的分支下

git branch checkout -b newbranch

合并分支

git merge branchname branchname

rebase操作

git rebase branchname branchname

远端仓库操作

克隆一个远端仓库

git clone URL/repodirectory

添加远端仓库

git remote add reponame URL/repodirectory

更新远端仓库的分支和数据

git fetch //默认更新远端master分支

git fetch reponame branchname //更新指定远端的分支

获取并合并远端仓库的分支到当前分支

git pull reponame branchname

eg: git pull origin master

上传本地分支和数据到远端仓库

git push reponame branchname

eg: git push origin master

跟踪远端仓库上的分支

git checkout —track origin/testbranch

git checkout -b test origin/testbranch

setUpBlog

image

安装brew

执行命令

1
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

安装wget

执行命令

1
$ brew install wget

安装nvm(node.js的版本管理工具)

1
$ wget -qO- https://raw.github.com/creationix/nvm/master/install.sh | sh

添加如下内容到~/.zshrc 配置文件

1
[ -s "/Users/`users`/.nvm/nvm.sh" ] && . "/Users/`users`/.nvm/nvm.sh" # This loads nvm

安装node.js(通过nvm安装)

1
$ nvm install 0.10

安装hexo

1
$ npm install -g hexo

创建hexo文件夹,并安装hexo组件

1
2
3
$ hexo init hexo
$ cd hexo
$ npm install

查看本地

输⼊入如下命令后,打开浏览器,并输⼊入localhost:4000来查看

1
2
$ hexo g
$ hexo s

登录github.com注册github账号

创建与github同名的repository

eg : github账号名位lfxfengxia,则创建lfxfengxia.github.io

部署到github上

如下所示编辑_config.yml

1
2
3
4
deploy:
type: github
repository: git@github.com:dorayox/dorayox.github.io.git
branch: master

输入如下命令,完成到github的部署,之后打开浏览器并输入dorayox.github.io来查看

1
2
$ hexo g
$ hexo d

上传文件到blog

在hexo目录下,创建新文件

eg : 创建新文件test

1
$ hexo new test

默认创建的新文件后缀问 .md文件,存在hexo/source/_posts/目录下

使用MOU打开新建的文件并完成编辑

1
$ mou source/_posts/test.md

将新建的文件声称网页

1
$ hexo g

上传到blog

1
$ hexo d

登录blog查看是否上传成功

http://lfxfengxia.github.io

image

image

NSLog 与 printf的不同

1. NSLog接收oc字符串作为参数,printf接收c语言的字符串作为参数
2. NSLog输出后会自动换行,printf在输出后不会自动换行
3. 使用NSLog时,需要包含头文件#import <Foundition/Foundition.h>;而使用printf时,需要包含头文件#include<stdio.h>
4. NSLog可以输出日期,时间戳,进程号等信息,而printf不能输出这些信息

常用术语

面向过程 : Procedure Oriented

面向对象 : Object Oriented ,简称OO

面向编程 : Object Oriented Programming,简称OOP

OC 语法

  1. 类的声明
    @interface 类名:父类(默认为 NSObject 该类时根类)

    {

        定义成员变量;(默认情况下,成员变量为protect类型,)

    }    

    ( 可以用@public将其定义为public类型,此时定义的属性或变量允许被外界访问)
    @property(nonatomic/atomic,readonly/readwrite,assign/strong/retain/wake)类型 属性名;(定义属性可以自动生成setter和getter方法)

    声明类方法;(标识 + 该方法向类发消息)

    声明实例方法; (标识 - 该方法向对象发消息) 声明类方法时 返回值最好定义为`instancetype`类型

    @end
  1. 类的实现

     @implemention 类名
    
     - 实例方法
    {
            实现代码; 
     }
    
     + 类fangfa
    { 
            实现代码; 
     }
    
     重写父类方法;
     如:descripition、 dealloc、init等
    
     @end
    

    3.创建对象

     1.包含所创建类的头文件
     2.类名 *对象名;
     2.1 类名 *对象名 = [[类名 alloc]init];(创建对象并为其分配内存、初始化)
     2.2 类名 *对象名 = [类名 new];(每次都会创建出新的对象,并且返回对象的地址。)
     3. 给对象赋值;(可以调用相应的类方法);
     4. 给对象发消息,完成所需要进行的操作;[对象 方法];
    
  2. 匿名对象

        方法调用:
    
            [[类名 new]方法];/[[[类名 alloc]init]方法];
    
        属性访问:
    
            [类名 new->属性 = 赋值;(外界访问定义为public类型的属性)
    

OC方法和函数的区别

1. OC方法的声明只能在@interface@end之间,只能在@implementation@end之间。即OC方法独立于类存在。
2. C函数不属于类,跟类没有联系,C函数所有权只属于定义函数的文件
3. C函数不能访问OC对象的成员变量。

OC语法细节

1. 成员变量不能在{}中进行初始化、不能直接拿去访问
2. 方法的声明不能写在@end之后
3. 方法不能当作函数一样调用
4. 成员变量、方法不能用static等关键字进行修饰

OC方法注意点

方法只有声明,没有实现(经典错误,系统提示警告)
方法没有声明,只有实现(编译器警告,但是可以调用,OC的弱语法)
编译的时候,访问没有定义的成员变量直接报错,调用没有的方法,只是警告
没有@interface,纸偶@implemenation也可以成功定义一个类
        @implemenation Dog : NSObject
        {
            int _age;
            NSString *_name;
        }

        - (void)print
        {
            NSLog(@"The dog's name is %@,ang de it's %d years old!",_name,_age);
        }
        @end

@implemenation 中不能声明和@interface一样的成员变量

OC中有`BOOL`基本数据类型,其值是`YES`和`NO`,而不是truefalse,它实际上是一种对带符号的自负类型(signed char)的定义(typedef),它使用8为存储空间。`YES定义为1NO定义为0`;

image

类方法he实例方法

  1. 类方法

     * 该方法是直接可以用类名来执行的方法(类本身会在内存中占据存储空间,里面有类/对象方法列表)
     * 以加号 + 开头
     * 只能用类名调用,对象不能调用
     * 类方法不能访问实例变量(成员变量)
     * 使用场合:当不需要访问成员变量时,尽量使用类方法
     * 类方法和对象方法可以同名
    
  2. 实例方法

     * 该方法是用对象名来执行的方法
     * 以减号 — 开头
     * 只能用对象名调用,类不能调用,该方法没有对象是不能被执行的
     * 对象方法能访问实例变量(成员变量)
    

setter和getter方法

  1. setter和getter方法的使用场合

     @public的成员可以随意被赋植,应该使用setget方法来管理成员变量的访问
    
  2. setter方法

    作用:用来设置成员变量,可以在方法里面过滤一些不合理的值
    命名规范:方法以set开头,而且后面跟上成员变量名,成员变量名必须首字母大写,尽量形参名称不要与成员变量名重名(成员变量名最好以下划线 _ 开头)
    返回值:一般为void
    
  3. getter方法

    作用:返回对象内部的成员变量
    命名规范:方法名和成员变量名同名
    返回值:一般与成员变量的类型相同  
    

self关键字

  1. 成员变量和局部变量同名

     当成员变量和局部变量同名时,采取就近原则,访问的是局部变量
     当self访问成员变量,区分同名的局部变量
    
  2. 使用细节

     1. 出现的地方:所有的OC方法中(对象方法/类方法),不能出现在函数
     2. 作用:
         使用“self.属性”访问当前方法中的成员变量
         使用“self-> 成员变量”访问当前方法中public成员变量
         使用“[self 方法]”调用方法(类方法/实例方法)
     3. 类方法中self只能调用类方法,实例方法中self只能调用实例方法
    

继承

  1. 继承的概念

     1. is-a机制
     2. 即当创建的多个类有共同的属性和行为时,可以抽出一个类作为父类,在父类中定义相同的属性,声明实现相同的行为(方法);
     3. 子类可以使用父类的所有属性和方法,并且子类可以在父类的基础上拓补自己的属性和方法,包括重写父类方法。重写父类方法时,子类对象会优先调用子类重写后的方法。
     4. 子类属性和方法访问的过程: 如果子类没有相应的方法或属性,则去访问父类,一次递进知道找到NSObject根类,如果仍然没有找到相对应的方法和属性,则报错。
    
  2. 继承的专业术语

     父类/超类    superclass
     子类 subclasssubclasses
    
  3. 继承的细节

     单继承,不支持多继承
     子类和父类不能有相同的成员变量
     子类可以重写父类中声明的方法(在代码运行时,oc确保调用相应类的重写方的实现)
    
  4. 继承的优缺点

     优点:
     在不改变原来模型的基础上,拓充方法
     建立了类与类的联系
     抽取了公共代码
    
     缺点:
     耦合性强
    
  5. super关键字

     super既不是参数,也不是实例变量,而是oc编译器提供的功能
     用于提供一种在子类中显示调用父类的方法    
    
  6. 继承的局限性

     父类不能访问子类属性、调用子类方法
     不能继承累簇(如 NSString累簇)
    

多态

  1. 多态的基本概念

     某一类事物的多种形态
     OC对象具有多态性
    
  2. 多态的体现

     主要体现在继承下:向不同的对象发相同的消息,其呈现的行为不一样。(如DrawShape程序中,向不同图像的对象发送draw消息,其打印结果是不同的)。
     子类对象可以赋值给父类指针;
     如:Father *f = [children new];
     父类指针可以访问对应的属性和方法
     如: f.age = 23;  
         [f study];
    
  3. 多态的好处

     用父类接收参数,节省代码
    
  4. 多态的局限性

     不能访问子类的属性(可以考虑强制转换)
    
  5. 多态的细节

     动态绑定,在运行时根据对象的类型确定动态调用的方法
    

复合

复合包括组合和聚合

hasa机制
组合和聚合表示将各个部分组合在一起,用于表达整体与部分的关系。在面向对象的编程思想里,就是用已有类的对象封装新的类。
  • 组合 :表示一种强的、严格的整体与部分的关系,部分和整体的生命周期一样。 比如:人和人头
  • 聚合 :表示一种弱的整体与部分的关系,比如: 汽车和轮胎

Foundition框架

1. OC集合只能存储OC对象,不能存储c语言中的基本数据类型,如intfloatenumstruct,且不能在集合中存储nil

字符串

  1. 不可变字符串 : NSString *string1;
  2. 可变字符串 : NSMutableString *string2;

    对可变字符串的操作:

    2.1 增加元素

    string2 appendFormat:@"hello"];

    2.2 删除元素

    [string2 replaceCharacterInRange:NAMakeRange(2,3)];

    2.3 修改元素(替换)

    [string2 replaceCharacterInRange:NAMakeRange(2,3)withString:@"word"];

  3. 字符串的操作

    3.1 比较

    //判断两个字符串是否相等,返回的是BOOL值

    [str1 isEqualTo:str2];

    NSCompareResult res = [str1 copmare:str2];

    不区分大小写的比较:caseInsensitiveCompare

    有选择参数的比较: [str compare:str2 option:NSStringCompareOption]

    NSStringCompareOption选项可以传入的参数

     enum {
                NSCaseInsensitiveSearch = 1,   不区分大小写
                NSLiteralSearch = 2,           对于相等的字符串逐个比较
                NSBackwardsSearch = 4,         从后向前比较
               NSAnchoredSearch = 8,          限制比较从开始还是结尾
                NSNumericSearch = 64,          对于数字按数字比较
               NSDiacriticInsensitiveSearch = 128,     不区分音节
                NSWidthInsensitiveSearch = 256,         忽略full-width half-width (如 Unicode code point U+FF41 和 Unicode code point U+0061 的字母 “a”is equal)
                NSForcedOrderingSearch = 512,           对于不区分大小写比较相等的字符串,强制返回NSOderedAscending or NSOrderedDeascending (如“aa” is grater than “AA”)
                NSRegularExpressionSearch = 1024        treated as an ICU-compatible regular expression
         };
    

    NSCompareResult 有三种值:

     NSOrderedSame  两字符串相等
     NSOrderedAscending  str1 < str2
     NSOrderedDeascending  str1 > str2;
    

    3.2 求长度

    NSUInteger strlen = [str1 length];

    3.3 大小写转换

    str2 = [str1 uupercaseString];

    str2 = [str1 lowercaseString];

    3.4 获取文件前缀、后缀

    str2 =[str1 hasPrefix:@"word"];

    str2 = [str1 hasSuffix:@"txt"];

    3.5 获取子串

    //获取str2在str1中的位置,即range.location and range.length

    range = [str1 rangOfString:str3];

    range = [str1 rangOfString:@"hello"];

    //获取str1 第6个位置之后的字符串赋值给str2

    str2 = [str1 substringFromIndex:6];

    //获取str1 从开始到第6个位置之间的字符串赋值给str2

    str2 = [str1 substringTOIndex:6];

    //获取str1 从第6个位置开始长度为5的字符串赋值给str2

    str2 = [str1 substringWithRange:NSMakeRange(6,7)];

    3.6 文件路径的转换

    //间文件路径字符串str1 = @“~/test.html”的路径转换为绝对路径赋值给str2

    str2 = [str1 stringByExpandingTildeInPath];

    //间文件路径字符串str1 = @“/users/qingyun/test.html”的路径转换为相对路径赋值给str2

    str2 = [str1 stringByAbbreviatingWithTildeInPath];

    3.7 文件路径的扩展名

    str2 = [str1 pathExtension]; 此时 str2 = @“html”;

    3.7 删除文件路径的后缀

    str2 = [str1 stringByDeletePathExtension]; 此时 str2 = @“~/test”;

    3.9 追加字符串

    str1 = @”hello word”;

    str2 = [str1 stringByAppendingFormat:@"wellcom"]; 此时 str2 = @“hello word wellcom”;

数组

  1. 不可变数组 : NSArray *array1;
  2. 可变数组 : NSMutableArray *array2;

    数组初始化:

    NSArray *array1 = [NSArray arrayWithObjects:@"hello",@"word",@"two",nil];

    NSArray *array1 = @[@12,@34,@"hello",@"error"];

    //创建空数组

    NSMutableArray *array2 = [NSMutableArray array];

    //用已有的数组创建新数组

    NSMutableArray *array2 = [NSMutableArray arrayWithArray:array];

    //创建一个数组,并预分配内存

    NSMutableArray *array2 = [NSMutableArray arrayWithCapacity:40];

    对可变数组的操作:

    2.1 增加元素

    [array2 addObjects:@"hello"];

    2.2 删除元素

    //删除下标为2的对象

    [array2 removeObjectsAtIndex:2];

    //删除一定范围内的所有@“hello”

    [array2 removeObject:@"hello" inRange:NSMakeRange(2, 3)];

    [array3 removeObjectIdenticalTo:@"is" inRange:NSMakeRange(1, 5)];

    //删除该数组内的所有@“hello”

    [array2 removeObjectIdenticalTo:@"hello"];

    2.3 修改元素(替换)

    [array2 removeObjectsAtIndex:2 withObject:@"dog"];

    [array2 removeObjectsAtIndex:2 withObject:str];

    [array2 removeObjectsInRange:NSMakeRang(0,2) withObjectFromArray:array];

    2.4 插入元素

    [array2 insertObjects:str1 AtIndex:2];

    2.5 访问数组某个对象

    array2[下标]

字典

  1. 不可变数组 : NSDictionary *dictionary1;
  2. 可变数组 : NSMutableDictionary *dictionary2;

    字典初始化:

    Dictionary *dictionary1 = [NSDictionary dictionaryWithObjectsAndKeys:str1,@"hello",str2,@"word",str3,@"two",nil];

    Dictionary *dictionary1 = @{@"num1":@12,@"num2":@34,@"str1":@"hello",@"str2":@"error"};

    //创建空字典

    NSMutableDictionary *dictionary2 = [NSMutableDictionary dictionary];

    //用已有的字典创建新字典

    NSMutableDictionary *dictionary2 = [NSMutableDictionary dictionaryWithDictionary:array];

    //创建一个字典,并预分配内存

    NSMutableDictionary *dictionary2 = [NSMutableDictionary dictionaryWithCapacity:40];

    对可变字典的操作:

    2.1 增加元素

    [dictionary2 addObjects:(id)forKey:@"key"];

    2.2 删除元素

    [dictionary2 removeObjectForKey:@"key"];

    2.3 修改元素(替换)

    [dictionary2 setObject:(id)forKey:@"key"];

    2.4 访问字典

    dictionary2[@“key”];

    [dictionary2 objectForKey:@"key"]

装箱-开箱

  1. 对基本数据类型的装箱-NSNumber

    //装箱方法1

    NSNumber *number = [NSNumber numberWithChar:'X'];

    NSNumber *number = [NSNumber numberWithINT:23];

    NSNumber *number = [NSNumber numberWithBOOL:YES];

    NSNumber *number = [NSNumber numberWithDouble:34.5];

    //装箱方法2

    @23,@34.5

    //开箱

    [number charValue];

    [number intValue];

    [number BOOLValue];

    [number DoubleValue];

  2. 对所有非对象类型的装箱(包括基本数据类型)- NSValue

    //对NSRect,NSPoint,NSRange装箱,也可以对基本数据类型进行装箱

    NSRect rect = NSMakeRect(10,20,30,40);

    NSValue *value = [NSvalue valueWithBytes:&rect objCType:@encode(NSRect)];

    int a = 5;

    NSValue *value = [NSvalue valueWithBytes:&a objCType:@encode(int)];

    //开箱

    NSRect rect2 = {0};

    [value getValue:&rect];

    int b = 0;

    [value getValue:&b];

    //仅对NSRect,NSPoint,NSRange装箱

    NSValue *value = [NSValue valueWithRect];

    NSValue *value = [NSValue valueWithRange];

    NSValue *value = [NSValue valueWithPoint];

    //开箱

    NSRect rect2 = {0};

    [value rectValue];

    NSRange range = {0};

    [value rangeValue];

    NSPoint point = {0};

    [value pointValue];

枚举

//normal enumerator

NSEnumerator *enumer = [array objectEnumerator];

id obj;
while (obj = [enumer nextObject]) {
    NSLog(@"%@",obj);
}

NSEnumerator *enumer2 = [array reverseObjectEnumerator];
while (obj = [enumer2 nextObject]) {
    NSLog(@"%@",obj);
}

//fast enumerator

for (id obj2 in array) {
    NSLog(@"%@",obj2);
}

类别

  1. 类别的简述

    • 为现有的类(自定义的类、第三方的类或者是系统定义的类)添加一些新的行为;
    • 类别可以解决继承不能为累簇添加新方法的问题。
  2. 类别的声明和实现

    格式: 类名 + 类别名

    如:为NSString 创建一个类别 NSString+NumberConvenience

    只要保证类别名称唯一,可以向一个类中添加任意数量的类别。

    声明:

    @interface NSString (NumberConvenience)

    - (NSNumber *)lengthAsNumber;

    @end

    实现:

    @implementation NSString (NumberConvenience)

    - (NSNumber *)lengthAsNumber
    {

    }

    @end

  3. 类别的优缺点

    缺点:

     * 只能添加方法,只可以访问原始类的实例变量,无法向类别中添加新的实例变量
     * 名称冲突。类别具有最高优先级,即当类别中定义与对应类中已有的方法同名的方法,对象调用该方法时,会优先调用类别中定义的方法。
     * 多个Category中如果实现了相同的方法,只有最后一个参与编译的才会有效   
    

    优点:

     * 将类的实现代码分散到多个不同文件或框架中。
     * 可以创建对类中私有方法的前向引用,
     * 向对象添加非正式协议。
    
  4. 使用类别实现类的扩展

    类的扩展等同于在类声明的源代码中声明一个无名的(即括号“ () ”里面为空)类别,并实现;

    • 类的扩展可以在源代码中使用
    • 可以添加实例变量作为类的私有变量和方法
    • 可以将只读权限改为读写权限
    • 创建数量不限
  5. 利用类别分散实现代码的优点

     . 在大型的项目中, 一个类的实现可能非常大,并且.m文件不能分离。但是使用类别可以将一个类的实现分散且有规律的组织在不同的文件中。还可以将一个类的实现分散到不同的框架中。 
     . 编程人员可以更加容易阅读代码并实现多人合作编码
     . 版本管理降低冲突
     . 维护人员更容易理解代码
    
  6. 非常正式协议

    非正式协议就是为NSObject类创建一个类别;

  7. 响应选择器

    • 使用@selector()编译指令来指定选择器,圆括号里是具体的方法名。如:
1
2
3
4
(有几个参数要有几个冒号“ : ”)
如:
@selector(setEngine:)
@selector(setTire:atIndex:)
 - 选择器的类型关键字:SEL
 - \- (BOOL)respondsToSelector:(SEL)@Selector; 使用此方法可以判断某一对象是否可以执行指定的方法。 
1
QYStudent *student = [[QYStudent alloc]init];
 如: 
1
[student respondToSelector:(SEL)@selector(study)]; //对对象student判断其是否有study这个方法,有的话返回值为YES,没有的话返回值为NO。

协议

  1. 基本用途

    • 可以用来声明一大堆方法(不能声明成员变量)
    • 只要某个类遵守了这个协议,就相当于拥有这个协议中的所有方法声明
    • 只要父类遵守了某个协议,就相当于子类也遵守了
  2. 格式
    @protocol 协议名

    方法声明列表

    @end

    某个类遵守某个协议

    @interface 类名 : 父类名<协议名>

    @end

  3. 关键字

    协议中有2个关键字可以控制方法是否要实现(默认是@required),在大多数情况下,用途在于程序员之间的交流

    • @required: 该关键字以下且@optional关键字以上的方法必须要实现(若不实现,编译器会发出警告
    • @optional: 该关键字以下且@required关键字以上的方法可以选择性的实现
  4. 协议遵守协议

    • 一个协议可以遵守其他多个协议,多个协议之间用逗号 , 隔开

      • 一个协议遵守了其他协议,就相当于拥有了其他协议中的方法声明

      @protocol 协议名称 <协议1, 协议2>

      @end

  5. 基协议

    • NSObject是一个基类,最根本最基本的类,任何其他类最终都要继承它
    • 其实还有一个协议,名字也叫NSObject,它是一个基协议,最根本最基本的协议
    • NSObject协议中声明很多最基本的方法,比如description、retain、release等
    • 建议每个新的协议都要遵守NSObject协议
  6. 定义变量时指定协议

    // NSObject类型的对象,并且要遵守NSCopying协议

    • NSObject *obj;

      // 任何OC对象,并且要遵守NSCoding协议

    • id obj2;

内存管理

内存管理机制:引用计数

  1. 引用计数的计算

    • alloc 、new 、copy(copy生成接收对象的一个副本) //使用这三个方法创建对象时,对象的引用计数器为1
      • - (id) retain; //给对象发送retain消息后,对象的引用计数器加1
      • - (void) release; //给对像发送release消息后,对象的引用计数器减1
      • - (void)dealloc; //当一个对象的引用计数器变为0而即将被销毁时,Objective-C自动向对 象发送一条dealloc消息,我们通常都会在自己的对象中重写dealloc方法
      • - (unsigned) retainCount;//获取当前对象的引用计数器的值
  2. 非ARC环境下内存的管理

    当某个对象被持有有,[对象名 retain];
    当某个对象不再被持有时,[对象名 release];

  3. ARC环境下内存的管理

    • 规则

      只要还有一个强指针变量指向对象,对象就会保持在内存中

    • 强引用,弱引用

      ➢ 默认所有实例变量和局部变量都是Strong指针

      ➢ 弱指针指向的对象被回收后,弱指针会自动变为nil指针,不会引发野指针错误。其修饰符号为__weak;

    • 注意点

      ➢    不能调用release、retain、autorelease、retainCount
      

      ➢ 可以重写dealloc,但是不能调用[super dealloc]

      ➢ @property : 想长期拥有某个对象,应该用strong,其他对象用weak

      ➢ 其他基本数据类型依然用assign

      ➢ 两端互相引用时,一端用strong、一端用weak

      1. 自动释放池
    • 自动释放池是一个存放实体的集合,这些实体可能是对象,这些对象能够被自动释放。
    • / - (id) autorelease; //是NSObject类提供的方法,此方法在某一个预定的时候,向对象发送release消息,返回值是接收消息的对象。实际上当给一个对象发送autorelease消息的时候,就是将这个对象添加到的自动释放池(NSAutoreleasePool)中,当自动释放池销毁时,会向该池中的所有对象发送release消息。

      如: - (NSString ) description
      {
      NSString
      desc;
      desc = [[NSString alloc] initWithFormat: @” I am %d years old”,29];
      return ([desc autorelease]);
      }

  4. 内存管理规则

    • 如果我使用了new , alloc 或者copy方法获得一个对象,则我必须释放或自释放该对象。
    • 如果你对对象调用了retain消息,那么你必须负责释放(release)这个对象,保证retain和release的使用次数相等。

拷贝

  1. 浅拷贝(shallow copy)

    不会复制所引用的对象,新复制的对象只会指向现有的引用对象上。(引用计数加 1 ,地址不变)

  2. 深拷贝(deep copy)

    真正意义的复制概念。得到的结果是多个,而非只是对象的引用。(引用计数 不变 ,地址发生变化)

  3. 关键字

    copy:对不可变的集合copy为浅拷贝,对可变的集合copy为深拷贝

    mutableCopy:对可变的或不可变的集合mutableCopy都是深拷贝,但是对于集合内部对象的拷贝时浅拷贝。

BLOCK

  1. 基本概念

    代码块本质上是和其他变量类似。不同的是,代码块存储的数据是一个函数体。使用代码块时,可以像调用其他标准函数一样,传入参数数,并得到返回值。

* Block封装了一段代码,可以在任何时候执行
* Block可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。
* 苹果官方建议尽量多用block。在多线程、异步任务、集合遍历、集合排序、动画转场用的很多
  1. 定义

     int (^MySum)(int, int) = ^(int a, int b) {
     return a+b;
     };
    

    定义了一个叫MySum的blocks对象,它带有两个int参数,返回int。等式右边就是blocks的具体实现

  2. 对变量的访问权限

    • 对全局变量具有读写权限
    • 对静态变量具有读写权限
    • 对局部变量只有访问权限(可以用__block修饰局部变量,这样可以对其进行修改)
  3. 与函数指针的对比

    定义函数指针
    int (p)(int,int);
    *定义Blocks

    int (^Blocks)(int,int);

    调用函数指针
    (p)(10, 20);
    *调用Blocks

    Blocks(10, 20);

  4. typedef和赋值

    • 在声明的同时定义变量,然后赋值
      int (^MySum)(int,int) = ^(int a,int b) {
      return a + b;
      };

    • 也可先用typedef先声明类型,再定义变量进行赋值
      typedef int (^MySum)(int,int);
      MySum sum = ^(int a,int b) {
      return a + b;
      };

KVC(Key Valuble Coding)

  1. 基本概念
    • 是一种间接更改对象状态(或者说是属性值)的方式:key-value coding 简称KVC.
    • 主要本质特点是采用字符串来标识对象的属性变量,并可以利用这个标识来更改对象的状态(或者说是属性值)
  2. 基本用法

    • / - (id)valueForKey:(NSString *)key //以key作为标识符,获取其对应的属性值
    • / - (void)setValue:(id)value forKey:(NSString *)key //以key作为标识符设置其对应的属性值。
  3. 调用机制

    • valueForKey:会首先查找以参数名命名(格式为-key或者isKey)的getter方法,如果找到的话则调用这个方法;如果没有找到这样的getter方法,它将会在对象内部寻找名称格式为_key或者key的实例变量,然后返回。
    • setValue:forKey:的机制跟valueForKey相似。它首先查找参数名命名的setter方法,如果找到的话则完成设置;如果没有找到setter方法, 则直接在类中找到名称格式为_key或者key的实例变量, 然后将value赋值给它。
  4. 键路径

    键路径的概念和表示:可以在对象和不同的变量名称之间用圆点分开来表示。

    • -(id)valueForKeyPath:(NSString *)keyPath //以keyPath作为标识符,获取其对应的属性值
    • -(void)setValue:(id)value forKeyPath:(NSString *)keyPath //以keyPath为标识符,设置其对应的属性的值。

通配符 《系统级别》

  1. {}

    touch {1,2,3,4,6,a,c,b,hello,t}.c

    // 同时创建 1.c,2.c,3.c,4.c,6.c,a.c,c.c,b.c,hello.c,t.c文件

  2. *

    ls *.c

    //列出所有以 .c为后缀的文件

  3. ?

    ls ??h*.c

    //列出第三个字符为“h”,且以.c为后缀的所有文件

  4. []

    ls [0-9].c

    //列出以数字0-9为文件名的.c文件

  5. !

    ls ![0-9].c

    //列出所有不是以数字0-9为文件名的.c文件

谓词

  1. 谓词的定义

    谓词使用了KVC机制。

    NSPredicate *predicate = [[NSPredicate prdicateWithFormat:@string]];

    //实历化一个谓词对象.

    NSArray predicateArr = [对象名 filteredArrayUsingPredicate predicate];

    //向对象发消息,过滤出满足谓词条件的内容,并存放到数组predicateArr中; (filteredArrayPredicate:NSPredicate 方法的返回值时NSArray 类型)

  2. 谓词中的操作符

    谓词操作符不区分大小写

    • 关系运算符

      { > < >= <= == != }

    • 逻辑运算符

      {&&(and) ||(or) !}

1
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name != 'lisi' and age > 12"];
* 范围运算符

    `{between in}`
1
2
3
4
predicate = [NSPredicate predicateWithFormat:@"age in {23,25}"];
//仅仅过滤出 age = 23 和 age = 25 的信息
predicate = [NSPredicate predicateWithFormat:@"age between {23,25}"];
//过滤出 23 >= age <= 25 的信息
* 通配符

    `{* ? 主要与like一起使用}`
1
2
predicate = [NSPredicate predicateWithFormat:@"name like '??a*'"];
//过滤name第三个字母为a的信息
* 字符串特有操作符

    `{contains like endswith beginswith [c]不区分大小写[d]不区分音节[cd]}`
1
2
predicate = [NSPredicate predicateWithFormat:@"name endswith[cd] 'u' and name contains[cd] 'ao'"];
//过滤name以‘u’结尾 且 包含 “ao”的信息
* 集合中的操作符

    `{ANY ALL}`
1
2
3
4
5
6
7
predicate = [NSPredicate predicateWithFormat:@"ALL age > 10"];
if ([predicate evaluateWithObject:Arr]) {
NSLog(@"evaluable");
}else {
NSLog(@"It's not evaluable ");
}
//判断数组Arr中的对象中age是否全部大于10
* 谓词模板

    `{$  %K}`
1
2
3
4
5
6
7
8
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age between $RANGE"];
NSArray *arr = @[@20,@50];
NSDictionary *dic = @{@"RANGE":arr};
//过滤 20 >= age <= 50的信息
NSString *keyPath = @"age";
predicate = [NSPredicate predicateWithFormat:@"%K > %@",keyPath,@20];
//过滤age > 20 的信息

正则表达式 《工具级别》

选择

| 竖直分隔符代表选择。例如,“grey | gray”可以匹配grey或gray

数量限定

  • +号代前面的字符至少要出现一次,可以出现多次。例如,“goo + gle”可以匹配google,gooogle,goooogle等
  • ?号代表前面的字符最多只能出现一次,可以不出现。例如,“colour?r”可以匹配color或者colour
  • 星号代表前面的字符可以不出现,可以出现一次或多次。例如,”0\42”匹配42,042,0042,0004等。
  • “{n}”代表前面的字符要出现n次,“{2,6}”代表前面的字符可以选择性的出现2-6次,例如,”go{2}gle”可以匹配google

匹配
“()”圆括号可以用来定义操作符的范围和优先度。例如,“gr(a|e)y”等价与“gray|grey”,”(grand)?father” 可以匹配father和grandfather。

^ $符号

  • ^符号代表开始,例如,“^b”可以匹配以字符b开始的一类字符串
  • $符号代表结束,例如,“x$”可以匹配以字符x结束的一类字符串,“^$”代表空

.符号
.点符号,代表可以是任意字符。例如,“^a.{3}[0-9]+eh(hello)$”可以匹配ad_dehhello,a23d4ehhello,asdf345ehhello等

1
以上规则可以综合使用

正则表达式可以用在grep,awk,sed,gas,find,等命令中,

  • grep | ‘[a-z]{5}zsh$’ dotfiles 过滤dotifiles目录下的所有文件及目录
  • ls | grep ‘^d’ ls命令列出当前目录下的以d开头的文件包括目录
  • grep | -R ‘hello’ ./* 递归的查看根路径下的所有包含hello字符串的内容(-RE 递归的查找,支持正则表达式)
  • find . -name ‘hello’查看名字为hello的文件的路径,
  • find . -type d 查看当前目录下的所有文件夹的路径
  • sed -RE ‘/^_.*(false)$/‘ /etc/passwd 查看passwd文件内容不是以下划线开始且以false结束的内容

image

accelerator-key

image

Base Key

command + c : 复制选中的内容

command + v : 粘贴已复制的内容

command + X : 剪贴已选中的内容

command + z : 撤销最近一次执行放入操作

command + / : 选中多行,一次注释多行

Move Key

ctrl + a : 移动光标到行首

ctrl + e : 移动光标到行尾

ctrl + p : 向上移动光标

ctrl + n : 向下移动光标

ctrl + b : 向左按字符移动光标

ctrl + f : 向右按字符移动光标

ctrl + option + b : 向左按符移动光标

ctrl + option + f : 向右按符移动光标

Select Key

ctrl + shift + b : 从光标处向左按字符选中

ctrl + shift + f : 从光标处向右按字符选中

ctrl + shift + p : 从光标处向上按行选中

ctrl + shift + n : 从光标处按行向上选中

Delete Key

ctrl + d : 删除贯标右边的字符,按字符删除

ctrl + h : 删除贯标左边的字符,按字符删除

ctrl + k : 删除光标所在位置之后的所有内容

Key — XCode

command + shift + 0 : 打开官方文档

command + shift + n : 创建一个工程

commanf + n : 创建一个类、协议、类别、累扩展等

command + b : 编译代码

command + r : 运行生成的代码

command + shift + k : 清空XCode之前的编译

command + shift + ->/<-;(左方向键) : 切换页面

commang + f : 在官方文档中调出搜索栏

comand + option + enter : 分栏

command + enter : 回到一栏

command + ctrl +左右键 : 不同页面的切换

shift + tab : 选中上一个

tab : 选中下一个

other key

command + ctrl + f : 切换当前应用程序界面的大小,同时将桌面背景消失,只显示当前应用程序

command + option + “+” : vim终端界面的大小切换

ctrl + 左右键 : 桌面快速切换

ctrl + 上键 : 已开应用程序,分布呈现在当前桌面

ctrl + 下键 : 呈现当前应用程序已开启的所有窗口,以及使用当前应用程序开启的历史文件

command + tab : 快速向后选择桌面已开启的应用程序

command + tab + shift : 快速向前选择桌面已开启的应用程序