# 私有变量和私有方法
##1.OC中的私有变量
- 在类的实现即.m文件中也可以声明成员变量,但是因为在其他文件中通常都只是包含头文件而不会包含实现文件,所以在.m文件中声明的成员变量是@private的。在.m中定义的成员变量不能和它的头文件.h中的成员变量同名,在这期间使用@public等关键字也是徒劳的。
```
- 能够使用父类的@public 类型的变量、@protected类型的变量
@private 类型的变量可以看到,但是不能使用
---
##2.OC中的私有方法
- 在.h中没有声明, 但在.m中实现,此时该方法被称为私有方法
# 对象和方法之间的关系


##1.对象作为方法的参数
- 对象作为方法参数传递是地址传递,因为对象是一个指针变量
- 在方法内部,可以通过对象形参,访问该对象的成员变量(如果该对象的该成员变量的访问权限是public的)
- 在方法内部,可以通过对象形参,调用该对象上的方法(给这个对象发送消息)
```
int main(int argc, const char * argv[])
{
// 1.创建士兵对象
Soldier *s1 = [Soldier new];
s1->_name = @"jack";
s1->_life = 10;
s1->_level = kSoldierLevel1;
// 2.创建枪对象
Gun *gun = [Gun new];
gun->_bulletCount = 100;
// 3.射击
[s1 fireByGun:gun];
}
@implementation Soldier
- (void)fireByGun:(Gun *)gun
{
[gun shoot];
}
@end
```
##2.对象作为方法的返回值
- 对象可以作为方法的返回值;
- 对象返回值的实质是返回指向该对象的指针,该对象是存储在堆内存中的。
- 由于堆内存是由程序员管理的,所以它不会因为函数结束而被销毁
```
@implementation Shop
- (Gun *)buyGun
{
Gun *gun = [Gun new];
gun->_bulletCount = 100;
return gun;
}
@end
# 结构体成员变量
##1.结构体成员变量
```
设计一个”学生“类 1> 属性
* 姓名
* 生日
用结构体作为类的实例变量(生日)
```
#import <Foundation/Foundation.h> //定义生日的结构体
typedef struct{
int year;
int month;
int day;
}MyDate;
@interface Person : NSObject
{
@public
NSString *_name;//定义姓名 MyDate _birthday;//定义生日
}
@end
@implementation Person
@end
int main(int argc, const char * argv[]) {
Person *p = [Person new];
p->_name = @"sb";
//因为结构体已经初始化为0了,在次初始化就报错了,但是可以逐个赋值。
//p->_birthday = {1990,12,3};
p->_birthday.year = 2014;
p->_birthday.month = 05;
p->_birthday.day = 12;
NSLog(@"%@的生日是:%d年%d月%d 日",p->_name,p->_birthday.year,p->_birthday.month,p->_birthday.day);
//也可以整体赋值
MyDate de={1993,11,11};
p->_birthday = de;
NSLog(@"%@的生日是:%d年%d月%d 日",p->_name,p->_birthday.year,p->_birthday.month,p->_birthday.day);
return 0;
}
```
# 对象作为方法的参数连续传递
##1.对象作为方法的参数连续传递
```
实现功能:士兵开枪 枪射击子弹
枪类:
名称:Gun 属性:型号(_size),子弹个数(_bulletCount) 行为:射击
人类
名称:Soldier
属性:姓名(_name) life level(等级) 行为:跑蹲开枪 跳
```
# description方法
##1.description基本概念
- NSLog(@"%@", objectA);这会自动调用objectA的descriptong方法来输出ObjectA的描述信息.
- descriptong方法默认返回对象的描述信息(默认实现是返回类名和对象的内存地址)
- description方法是基类NSObject 所带的方法,因为其默认实现是返回类名和对象的内存地址, 这样的话,使用NSLog输出OC对象,意义就不是很大,因为我们并不关心对象的内存地址,比较关心的是对象内部的一些成变量的值。因此,会经常重写description方法,覆盖description方法 的默认实现
---
##2.description重写的方法
- 对象方法
```
/**对象方法:当使用NSLog输出该类的实例对象的时候调用*/
-(NSString *) description
{
return [NSString stringWithFormat:@"狗腿数:%d,狗眼数%d\n",_legNum,_eyeNum];
}
```
- 类方法
```
/**类方法:当使用NSLog输出该类的类对象的时候调用*/
+(NSString *) description
{
return @"+开头头的description方法";
}
```
##3.description陷阱
- 千万不要在description方法中同时使用%@和self,下面的写法是错误的
```
- (NSString *)description {
return [NSString stringWithFormat:@"%@", self];
}
```
- 同时使用了%@和self,代表要调用self的description方法,因此最终会导致程序陷入死循环,循 环调用description方法
- 当[NSString stringWithFormat:@“%@”, self]; 使用它时,循坏调用,导致系统会发生运行时错误。
- 当该方法使用NSLog(“%@”,self) 时候, 系统做了相关的优化,循坏调用3次后就会自动退出
# NSString 类介绍及用法
##1.NSString常见方法
- NSString是 Objective-C 中核心处理字符串的类之一
- 创建常量字符串,注意使用“@“符号。
```
NSString *astring = @"This is a String!";
```
- 创建空字符串,给予赋值。
```
NSString *string = [NSString new];
string = @"李南江";
```
- 创建格式化字符串:占位符(由一个%加一个字符组成)
```
[NSString stringWithFormat:@"江哥%i岁了", 30];
```
##2.NSString字符串长度计算
- 通过调用NSString类的对象方法 length 可以获得字符串的长度
- 字符串长度是指该字符串中一共有多个字符(无论是中文还是英文)
+ 纯英文字符
```
NSString *str = @"lnj";
NSLog(@"length = %i", [str length]);
输出结果:3
```
+ 中英文混合
```
NSString *str = @"lnj李";
NSLog(@"length = %i", [str length]);
输出结果:4
```
+ 纯中文
```
NSString *str = @"李南江";
NSLog(@"length = %i", [str length]);
输出结果:3
```
> ```NSUInteger 就是 unsigned long
源码: typedef unsigned long NSUInteger;```
---
# OC多文件开发介绍
##1.为什么要使用多文件
- 一个真正的iOS项目中可能会有成百上类,如果这些类都写在一个文件中,那么文件就会很大,想找到自己需要类都变的异常困难,开发效率低下
- 一个iOS项目可能会有多个人开发,如果多个人同时修改一个文件,那么就很可能会产生冲突,比如这个增加一个方法,那个人把这方法删掉了。另外就是当把多个人写功能合并起来的时候,也非常困难,写到一个文件中,无法顺畅的进行团队合作。
---
##2.@interface和@implementation的分工
- @interface就好像暴露在外面的时钟表面
- @implementation就好像隐藏在时钟内部的构造实现

---
##3.在OC中如何进行多文件开发?
- 在工作中,通常把不同的类放到不同的文件中,每个类的声明和实现分开
+ 声明写在.h头文件中,
+ 实现写在相应的.m文件中去,
+ 类名是什么,文件名就是什么。
```
假设有两个类,分别是Person类和Dog类,则通常有下面五个文件:
(1)Person.h Person类的声明文件
(2)Person.m Person类的实现文件
(3)Dog.h Dog类的声明文件
(4)Dog.m Dog类的实现文件
(5)Main.m 主函数(程序入口) 在主函数以及类的实现文件中要使用#import包含相应的头文件。
```
##4.使用多文件开发好处
- 显著提高团队协作的效率
- 提高程序的开发速度
- 提高程序的可维护性
- 提高代码的可读性
---
# \#pragma mark指令
##1.\#pragma mark指令的使用
- 功能:简单来说就是对代码的分组,方便代码查找和导航用的 它们告诉Xcode编译器,要在编辑器窗格顶部的方法和函数弹出菜单中将代码分隔开。一些类(尤其是一些控制器类)可能很长,方法和函数弹出菜单可以便于代码导航。此时加入#pragma 指令(#pragma是一个编译指令)对代码进行逻辑组织很有效果。
- 一个类里我们总会有一些方法的功能与性质是相差不多的,你可能会有把方法们分组的想 法。Xcode已经有了类似的支持,它就是 #pragma mark。
+ 分组: #pragma mark 分组(标识)名称

+ 分隔线: #pragma mark -

+ 分割线加分组: #pragma mark - 分组(标识)名称

# Xcode模板修改
##1.修改项目模板
- 项目模板就是创建工程的时候选择的某一个条目, Xcode会根据选择的条目生成固定格式的项目
+ 例如想创建一个命令行项目就选择Command Line Tool

- 如何修改项目模板
+ 1.找到Xcode, 右键"显示包内容"

+ 打开"/Applications/Xcode.app/Contents/Developer/Library/Xcode/Templates/Project\ Templates/Mac/Application" 文件夹
* 在/Application文件夹中能够找到所有和OS X Application界面对应的文件夹

+ 修改Command Line Tool模板
* 打开"Command Line Tool.xctemplate"文件夹, 发现和"改Command Line Tool模板"一一对应

* 打开"TemplateInfo.plist文件"发现和"改Command Line Tool模板"中内容对应

* 修改"TemplateInfo.plist文件"中的内容

- 注意:
+ 修改最好重启Xcode
+ 如果发现不能修改, 可以将文件拖到桌面后再修改, 或者修改文件的权限后再修改



- 练习: 修改main文件模板
+ 因为main文件是随着项目的创建自动创建的, 所以想要修改main文件的模板其实就是修改项目模板
+ 同样打开"TemplateInfo.plist文件"找到对应数据后直接修改重启Xcode即可
+


---
##2.修改类的头部信息
- 找到对应类对应的类文件模板. (因为类是创建项目之后手动创建的, 而不是随着项目的创建自动创建的, 所以修改类文件模板和项目模板并不是修改同一个文件)
+ 打开"/Applications/Xcode.app/Contents/Developer/Library/Xcode/Templates/File\ Templates/Source/Cocoa\ Class.xctemplate"文件夹

+ 找到继承Objective-C对应的文件夹

+ 修改对应的模板文件


---