iOS基础概念注意点
2016-07-22 10:24
309 查看
1.#include<> && #include””的区别
#include<>
<>会先去开发工具的编译器环境下查找
+ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.1.sdk/usr/include/
找不到再去系统的环境下查找
+ /usr/include/stdio.h
#include””
“”会先在当前文件夹下面查找,找不到再去编译器环境下查找,找不到再去系统的环境下查找
作用:
将""或者<>中的内容完全拷贝过来
注意:
include后面不一定要写文件名称,也可以写路径(相对路径/全路径)
2.#import && @class
由于import是一个预编译指令,他会将”’中的文件拷贝到import所在的位置
import有一个特点,只要””中的文件发生了变化,那么import就会重新拷贝一次(更新操作)
@class仅仅是告诉编译器,@class后面的名称是一个类,不会做任何拷贝操作
注意:由于@class仅仅是告诉编译器后面的名称是一个类,所以编译器并不知道这个类中有哪些属性和方法,所以在.m中使用这个类时需要import这个类,才能使用
总结:
1.如果都在.h中import,加入A拷贝了B,B拷贝了C,如果C被修改了,那么B和A都需要重新拷贝。也就是说如果都在.h中拷贝,只要有间接关系都会重新拷贝;如果在.h中用@class,在.m中用import,那么如果一个文件发生了变化,只有和这个文件有直接关系的那个文件才重新拷贝;所以在.h中用@class可以提升编译效率
2.如果两个类相互拷贝,例如A拷贝B,B拷贝A,这样会报错;解决方法:在.h中用@class,在.m中用import;因为如果在.h中都用import,那么相互拷贝会形成死循环,而在.h中用@class,那么不会做任何拷贝操作,在.m中用import只会拷贝对应的文件,并不会形成死循环
3.C保存字符串的两种方式
char str[] = “chris”;
存储到位置:栈
特点:相同的字符串会重复的分配存储空间;字符串可以修改
char *str = “chris”
存储到位置:常量区
特点:相同的字符串不会重复的分配存储空间;字符串不可以修改
4.静态数据类型 && 动态数据类型
1.默认情况下所有的数据类型都是静态数据类型
2.静态数据类型的特点:
在编译时就知道变量的类型,
知道变量中有哪些属性和方法
在编译的时候就可以访问这些属性和方法,
并且如果是通过静态数据类型定义变量,
如果访问了不属于静态数据类型的属性和方法,
那么编译器就会报错
3.动态数据类型的特点:
在编译的时候编译器并不知道变量的真实类型,
只有在运行的时候才知道它的真实类型
并且如果通过动态数据类型定义变量,
如果访问了不属于动态数据类型的属性和方法,
编译器不会报错
caution:
通过静态数据类型定义变量,不能调用子类特有的方法
通过动态数据类型定义变量,
可以调用子类特有的方法
通过动态数据类型定义的变量,
可以调用私有方法
弊端:
由于动态数据类型可以调用任意方法,所以有可能调用到不属于自己的方法,
而编译时又不会报错, 所以可能导致运行时的错误
应用场景:
多态,可以减少代码量,
避免调用子类特有的方法需要强制类型转换
id obj = [Person new];
[obj sleep];
[obj test];
[obj eat];
id obj2 = [Student new];
[obj2 eat];
[obj2 test];
为了避免动态数据类型引发的运行时的错误,一般情况下如果使用动态数据类型定义一个变量,在调用这个对象的方法之前会进行一次判断,
判断当前对象是否能够调用这个方法
id obj = [Studentnew];
/*
if ([obj isKindOfClass:[Student class]]) {
// isKindOfClass ,
判断指定的对象是否是某一个类,
或者是某一个类的子类
[obj eat];
}
*/
if ([objisMemberOfClass:[Studentclass]])
{
// isMemberOfClass :
判断指定的对象是否是当前指定的类的实例
[obj eat];
}
5.id && instancetype
id在编译的时候不能判断对象的真实类型
instancetype在编译的时候可以判断对象的真实类型
id可以用来定义变量,可以作为返回值,可以作为形参
instancetype只能用于作为返回值
6.KVC注意点
不要滥用kvc
因为kvc要把字符串类型的属性名称和值转换后才能赋值,所以性能不是很高
kvc是通过字符串类型的键去查找对应的属性进行赋值,所以有可能写错,但是写错后再编译时不会报错,只会在运行时报错
7.类对象的继承关系
类的本质:
类其实也是一个对象,
这个对象会在这个类第一次被使用的时候创建
只要有了类对象,
将来就可以通过类对象来创建实例对象
实例对象中有一个isa指针,指向创建自己的类对象
类对象中保存了当前对象所有的对象方法
当给一个实例对象发送消息的时候,
会根据实例对象中的isa指针去对应的类对象中查找
8.类方法和对象方法的区别
1. 对象方法以-开头;类方法以+开头
2. 对象方法必须用对象调用;类方法必须用类来调用
3. 对象方法中可以直接访问属性(成员变量);类方法中不可以直接访问属性(成员变量)
4. 类方法和对象方法可以进行相互调用
对象方法中可以直接调用类方法
类方法中间接调用对象方法(不建议这样使用)
类方法中可以直接调用其他类方法
对象方法中可以直接调用对象方法
类方法的应用场景
如果方法中没有使用到属性,那么能用类方法就用类方法
类方法的执行效率比对象方法高
类方法一般用于定义工具方法
字符串查找,文件操作,数据库操作
9.static变量
当使用static来修饰局部变量,那么会延长局部变量的生命周期,并且会更改局部变量存储的位置,将局部变量从栈转移到静态区中
只要使用static修饰局部变量之后,当执行到定义局部变量的代码就会分配存储空间,但是只有程序结束才会释放该存储空间
static int b =0;
b++; // 1 2
应用场景:
当某个方法的调用频率非常高,而该方法中有些变量的值是固定不变的,那么这个时候就可以使用static修饰该变量,让该变量只开辟一次存储空间,这样可以提升程序的效率和性能
void demo(int r)
{
static double pi =3.1415926; //
固定
double res = pi * r * r;
printf(@"res = %lf\n", res);
}
10.NSValue包装结构体
typedef struct{
int age;
char *name;
double height;
}Person;
Person p = {30,"chris",1.75};
// valueWithBytes: 接收一个指针,需要传递需要包装的结构体的变量的地址
// objCType:
需要传递需要包装的数据类型
NSValue *pValue = [NSValuevalueWithBytes:&pobjCType:@encode(Person)];
NSArray *arr =
@[pValue];
NSLog(@"%@", arr);
//从NSValue中取出自定义的结构体变量
Person res;
[pValue getValue:&res];
NSLog(@"age = %i, name = %s, height = %f", res.age,
res.name, res.height);
11.变量所占字节
12.iOS documents目录
13.main函数
// 系统在启动程序的时候,会给我们的程序传递一些参数
// argc : 就是系统传递进来的参数个数,默认是1
// argv : 就是系统传递进来的参数实际的值,默认是程序的名称
int main(int argc,const
char * argv[]) {
printf("argc = %i\n", argc);
printf("argv = %s\n", argv[0]);
printf("argv = %s\n", argv[1]);
// return
结束函数
// 0 : 返回给操作系统,如果返回0,
代表程序整除结束,如果返回其它值代表程序非正常结束
return 0;
}
14.修改项目模板路径
修改项目模板以及main函数中的内容
/Applications/Xcode.app/Contents/Developer/Library/Xcode/Templates/Project Templates/Mac/Application/Command Line Tool.xctemplate/
修改OC文件头部的描述信息
/Applications/Xcode.app/Contents/Developer/Library/Xcode/Templates/File Templates/Source/Cocoa Class.xctemplate
9.NSValue包装结构体
1. 对象方法以-开头;类方法以+开头
2. 对象方法必须用对象调用;类方法必须用类来调用
3. 对象方法中可以直接访问属性(成员变量);类方法中不可以直接访问属性(成员变量)
4. 类方法和对象方法
方法的调用顺序:
1.分类
2.本类
3.父类
// 注意:如果分类中有和原有类同名的方法,
会调用分类中的方法
// 也就是说会忽略原有类的方法
在iOS开发中,app的可见范围是由启动界面决定,如果没有设置启动界面,默认可视范围是3.5inch(320
* 480),如果设置了,就会自动自动识别当前模拟器的可视范围
#include<>
<>会先去开发工具的编译器环境下查找
+ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.1.sdk/usr/include/
找不到再去系统的环境下查找
+ /usr/include/stdio.h
#include””
“”会先在当前文件夹下面查找,找不到再去编译器环境下查找,找不到再去系统的环境下查找
作用:
将""或者<>中的内容完全拷贝过来
注意:
include后面不一定要写文件名称,也可以写路径(相对路径/全路径)
2.#import && @class
由于import是一个预编译指令,他会将”’中的文件拷贝到import所在的位置
import有一个特点,只要””中的文件发生了变化,那么import就会重新拷贝一次(更新操作)
@class仅仅是告诉编译器,@class后面的名称是一个类,不会做任何拷贝操作
注意:由于@class仅仅是告诉编译器后面的名称是一个类,所以编译器并不知道这个类中有哪些属性和方法,所以在.m中使用这个类时需要import这个类,才能使用
总结:
1.如果都在.h中import,加入A拷贝了B,B拷贝了C,如果C被修改了,那么B和A都需要重新拷贝。也就是说如果都在.h中拷贝,只要有间接关系都会重新拷贝;如果在.h中用@class,在.m中用import,那么如果一个文件发生了变化,只有和这个文件有直接关系的那个文件才重新拷贝;所以在.h中用@class可以提升编译效率
2.如果两个类相互拷贝,例如A拷贝B,B拷贝A,这样会报错;解决方法:在.h中用@class,在.m中用import;因为如果在.h中都用import,那么相互拷贝会形成死循环,而在.h中用@class,那么不会做任何拷贝操作,在.m中用import只会拷贝对应的文件,并不会形成死循环
3.C保存字符串的两种方式
char str[] = “chris”;
存储到位置:栈
特点:相同的字符串会重复的分配存储空间;字符串可以修改
char *str = “chris”
存储到位置:常量区
特点:相同的字符串不会重复的分配存储空间;字符串不可以修改
4.静态数据类型 && 动态数据类型
1.默认情况下所有的数据类型都是静态数据类型
2.静态数据类型的特点:
在编译时就知道变量的类型,
知道变量中有哪些属性和方法
在编译的时候就可以访问这些属性和方法,
并且如果是通过静态数据类型定义变量,
如果访问了不属于静态数据类型的属性和方法,
那么编译器就会报错
3.动态数据类型的特点:
在编译的时候编译器并不知道变量的真实类型,
只有在运行的时候才知道它的真实类型
并且如果通过动态数据类型定义变量,
如果访问了不属于动态数据类型的属性和方法,
编译器不会报错
caution:
通过静态数据类型定义变量,不能调用子类特有的方法
通过动态数据类型定义变量,
可以调用子类特有的方法
通过动态数据类型定义的变量,
可以调用私有方法
弊端:
由于动态数据类型可以调用任意方法,所以有可能调用到不属于自己的方法,
而编译时又不会报错, 所以可能导致运行时的错误
应用场景:
多态,可以减少代码量,
避免调用子类特有的方法需要强制类型转换
id obj = [Person new];
[obj sleep];
[obj test];
[obj eat];
id obj2 = [Student new];
[obj2 eat];
[obj2 test];
为了避免动态数据类型引发的运行时的错误,一般情况下如果使用动态数据类型定义一个变量,在调用这个对象的方法之前会进行一次判断,
判断当前对象是否能够调用这个方法
id obj = [Studentnew];
/*
if ([obj isKindOfClass:[Student class]]) {
// isKindOfClass ,
判断指定的对象是否是某一个类,
或者是某一个类的子类
[obj eat];
}
*/
if ([objisMemberOfClass:[Studentclass]])
{
// isMemberOfClass :
判断指定的对象是否是当前指定的类的实例
[obj eat];
}
5.id && instancetype
id在编译的时候不能判断对象的真实类型
instancetype在编译的时候可以判断对象的真实类型
id可以用来定义变量,可以作为返回值,可以作为形参
instancetype只能用于作为返回值
6.KVC注意点
不要滥用kvc
因为kvc要把字符串类型的属性名称和值转换后才能赋值,所以性能不是很高
kvc是通过字符串类型的键去查找对应的属性进行赋值,所以有可能写错,但是写错后再编译时不会报错,只会在运行时报错
7.类对象的继承关系
类的本质:
类其实也是一个对象,
这个对象会在这个类第一次被使用的时候创建
只要有了类对象,
将来就可以通过类对象来创建实例对象
实例对象中有一个isa指针,指向创建自己的类对象
类对象中保存了当前对象所有的对象方法
当给一个实例对象发送消息的时候,
会根据实例对象中的isa指针去对应的类对象中查找
8.类方法和对象方法的区别
1. 对象方法以-开头;类方法以+开头
2. 对象方法必须用对象调用;类方法必须用类来调用
3. 对象方法中可以直接访问属性(成员变量);类方法中不可以直接访问属性(成员变量)
4. 类方法和对象方法可以进行相互调用
对象方法中可以直接调用类方法
类方法中间接调用对象方法(不建议这样使用)
类方法中可以直接调用其他类方法
对象方法中可以直接调用对象方法
类方法的应用场景
如果方法中没有使用到属性,那么能用类方法就用类方法
类方法的执行效率比对象方法高
类方法一般用于定义工具方法
字符串查找,文件操作,数据库操作
9.static变量
当使用static来修饰局部变量,那么会延长局部变量的生命周期,并且会更改局部变量存储的位置,将局部变量从栈转移到静态区中
只要使用static修饰局部变量之后,当执行到定义局部变量的代码就会分配存储空间,但是只有程序结束才会释放该存储空间
static int b =0;
b++; // 1 2
应用场景:
当某个方法的调用频率非常高,而该方法中有些变量的值是固定不变的,那么这个时候就可以使用static修饰该变量,让该变量只开辟一次存储空间,这样可以提升程序的效率和性能
void demo(int r)
{
static double pi =3.1415926; //
固定
double res = pi * r * r;
printf(@"res = %lf\n", res);
}
10.NSValue包装结构体
typedef struct{
int age;
char *name;
double height;
}Person;
Person p = {30,"chris",1.75};
// valueWithBytes: 接收一个指针,需要传递需要包装的结构体的变量的地址
// objCType:
需要传递需要包装的数据类型
NSValue *pValue = [NSValuevalueWithBytes:&pobjCType:@encode(Person)];
NSArray *arr =
@[pValue];
NSLog(@"%@", arr);
//从NSValue中取出自定义的结构体变量
Person res;
[pValue getValue:&res];
NSLog(@"age = %i, name = %s, height = %f", res.age,
res.name, res.height);
11.变量所占字节
12.iOS documents目录
13.main函数
// 系统在启动程序的时候,会给我们的程序传递一些参数
// argc : 就是系统传递进来的参数个数,默认是1
// argv : 就是系统传递进来的参数实际的值,默认是程序的名称
int main(int argc,const
char * argv[]) {
printf("argc = %i\n", argc);
printf("argv = %s\n", argv[0]);
printf("argv = %s\n", argv[1]);
// return
结束函数
// 0 : 返回给操作系统,如果返回0,
代表程序整除结束,如果返回其它值代表程序非正常结束
return 0;
}
14.修改项目模板路径
修改项目模板以及main函数中的内容
/Applications/Xcode.app/Contents/Developer/Library/Xcode/Templates/Project Templates/Mac/Application/Command Line Tool.xctemplate/
修改OC文件头部的描述信息
/Applications/Xcode.app/Contents/Developer/Library/Xcode/Templates/File Templates/Source/Cocoa Class.xctemplate
9.NSValue包装结构体
1. 对象方法以-开头;类方法以+开头
2. 对象方法必须用对象调用;类方法必须用类来调用
3. 对象方法中可以直接访问属性(成员变量);类方法中不可以直接访问属性(成员变量)
4. 类方法和对象方法
方法的调用顺序:
1.分类
2.本类
3.父类
// 注意:如果分类中有和原有类同名的方法,
会调用分类中的方法
// 也就是说会忽略原有类的方法
在iOS开发中,app的可见范围是由启动界面决定,如果没有设置启动界面,默认可视范围是3.5inch(320
* 480),如果设置了,就会自动自动识别当前模拟器的可视范围
相关文章推荐
- textfield 限制长度 iOS
- iOS错误之-Presenting view controllers on detached view controllers is discouraged
- iOS 8 AutoLayout与Size Class
- iOS Crash之NSInternalInconsistencyException
- iOS开发之AFNetworking 3.0.4使用
- CADisplayLink的调用足够精确吗?
- IOS在子线程中使用定时器,将定时器添加至RunLoop中
- iOS复习安排
- iOS 推送证书生成pem
- iOS开发——pch文件添加和使用
- IOS 本地和远程推送通知详解
- iOS 饼状图
- nagios监控客户端报错/usr/bin/perl^M: bad interpreter: No such file or directory
- nagios监控客户端报错/usr/bin/perl^M: bad interpreter: No such file or directory
- iOS 用户登录 sh1加密
- iOS 9 Core Spotlight搜索实例代码
- iOS6、7、8、9新特性汇总和适配说明
- 【代码笔记】iOS-中国地图
- 【代码笔记】iOS-中国地图
- OC_图片拉伸的几种方式(拉伸、切片)