一. 对象的存储细节
类创建对象,每个对象在内存中都会占据一定的存储空间,每个对象都有自己一份独有的成员变量,所有的对象共有类的成员方法,方法在整个内存中只有一份,类本身在内存中占据一份存储空间,类的方法存储于此。我们先来了解一下内存的划分,内存分为5个区域,栈区/堆区/BBS段/数据区/代码区。其中:
栈区:存储局部变量
堆区:程序运行时动态分配的空间
BBS段:没有初始化的全局变量和静态变量
数据区:已经初始化的全局变量和静态变量和字符串常量
代码区:保存代码的二进制
当我们new一个对象的时候,`Person *p=[Person new];`我们的对象存放在那个区,p有存放在那个区啦?其实只要new一下,就会在堆区开辟一个空间。实例变量保存在堆区,对象方法保存在代码区。当创建一个对象的时候:Person *p1 = [Person new] 做了三件事情:
1,申请堆内存空间;
2,给实例变量初始化
3,返回所申请空间的首地址;
用下图来详细描述在内存空间中得存储情况:
二、函数和对象方法的区别
对象方法:-(返回值类型)方法名;
-(void)run;
(1)对象方法的实现在@implementation…@end中
对象方法的声明只能写在 @interface…@end中间
(2)对象方法都以-号开头
(3)对象方法只能由对象来调用
(4)对象方法归对象所有
函数: void run(){
}
(1)所有的函数都是平行的
(2)函数不存在隶属关系
(3)使用的时候可以直接调用
(4)不可以访问对象中的成员变量
(5)函数属于整个文件,可以写在文件中的任何位置,包括@implementation…@end中,但写在 @interface…@end会无法识别,函数的声明可以在main函数内部也可以在main函数外部。
(6)函数不允许嵌套定义,可以嵌套调用
#import <Foundation/Foundation.h>
void test(){
printf("this is test!\n");
}
#pragma mark - Person类
@interface Person :NSObject
{
//实例变量
NSString *_name;
int _age;
}
-(void)run;
@end
//Person类的实现
@implementation Person
-(void)run{
NSLog(@"人在散步!");
}
//放到此处可以
//void test1(){
//
// printf("this is test!\n %d",_age);
//}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
void test(); //函数的声明
void test1();
test1();
test();
Person *p = [Person new];
[p run];
}
return 0;
}
三、对象和方法之间的关系
1、对象作为方法的参数
假设有Person类: Person类有name、sex属性
假设实例化Person的对象
Person *p = [Person new]; p->_name =@"凤姐"; p->_sex = @"女";
......
......
-(void) displayPerson:(Person *)person{
}
......
NSLog("姓名:%@",person->_name); NSLog("姓名:%@",person->_sex);
2、对象做方法的返回值
-(Person *)changePerson:(Person *)person{
person->name = @"唐僧"; person->sex =@"男";
person->age = person->age+1;
return person;
}
Person *p2 = [d changePerson:p1]; [d displayPerson:p2];
四、练习题
/*
1.设计一个”狗“类
1> 属性
* 颜色
* 速度(单位是m/s)
* 性别
* 体重(单位是kg)
2> 行为
* 吃:每吃一次,体重增加0.5kg,输出吃完后的体重
* 吠(叫):输出所有的属性
* 跑:每吃一次,体重减少0.5kg,输出速度和跑完后的体重
* 比较颜色:跟别的狗比较颜色,如果一样,返回YES,不一样,返回NO
* 比较速度:跟别的狗比较速度,返回速度差(自己的速度 - 其他狗的速度)
*/
#import <Foundation/Foundation.h>
//用枚举装狗狗的颜色情况
typedef enum Color{YELLOW,BLACK,WRITE}dogColor;
// 创建Dog类
@interface Dog:NSObject
{ @public
int _color;
int _speed;
NSString *_sex;
float _weight;
}
//声明Dog行为的方法
-(void)eat:foodName;
-(void)jiao;
-(void)run:(int)num;
-(BOOL)cmpColor:(int)dog1Color andDog2Color:(int)dog2Color;
-(void)cmpSpeed:(int)dog1Speed andDog2Color:(int)dog2Speed;
@end
@implementation Dog
/** * 狗吃食物后体重上升 */
-(void)eat:foodName{
//打印出狗吃的食物
NSLog(@"狗吃了:%@",foodName);
//返回狗的体重
_weight+=0.5;
NSLog(@"体重为%.2f",_weight);
}
/** * 狗叫输出狗的属性 */
-(void)jiao{
NSLog(@"狗的颜色为%d,速度为%d,性别为%@,体重为%.2f",_color,_speed,_sex,_weight);
}
/** * 狗跑步锻炼体重减少 */
-(void)run:(int)num{
NSLog(@"狗以%d的速度跑了%d次",_speed,num);
_weight-=0.5*num;
NSLog(@"体重为%.2f",_weight);
}
/** * 两只狗比较颜色 * * @param dog1Color 第一只狗的颜色 * @param dog2Color 第二只狗的颜色 */
-(BOOL)cmpColor:(int)dog1Color andDog2Color:(int)dog2Color{
if (dog2Color==dog1Color) {
return YES;
}
else return NO;
}
/** * 比较狗的速度 * * @param dog1Speed 第一只狗的速度 * @param dog2Speed 第二只狗的速度 */
-(void)cmpSpeed:(int)dog1Speed andDog2Color:(int)dog2Speed{
if (dog2Speed==dog1Speed) {
NSLog(@"两只狗狗一样的速度");
}
else NSLog(@"狗狗速度相差:%d",dog1Speed-dog2Speed);
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
//创建狗类的对象dog1和dog2
Dog *dog1=[Dog new];
dog1->_weight=56;
dog1->_speed=5;
dog1->_sex=@"公狗";
dog1->_color=YELLOW;
Dog *dog2=[Dog new];
dog2->_weight=50;
dog2->_speed=4;
dog2->_sex=@"母狗";
dog2->_color=BLACK;
//输出狗狗的信息
[dog1 jiao];
[dog2 jiao];
//[dog1 eat:@"土豆"];
// [dog1 run:2];
BOOL flag;
flag=[dog1 cmpColor:dog1->_color andDog2Color:dog2->_color];
NSLog(@"颜色%d",flag);
[dog1 cmpSpeed:dog1->_speed andDog2Color:dog2->_speed];
}
return 0;
}