oc语言学习之基础知识点介绍(二):类和对象的进一步介绍
一、类、对象在内存中的存储
/*
内存分区:
栈:局部变量
堆:程序员自己写代码申请开辟的 程序员自己维护,编译器现在帮我们自动优化了,它在合适的给我们加上了释放空间的语句,所以我们现在写的对象不会造成内存泄露 全局区:所有的全局变量和静态变量
常量区:所有的常量
代码区:程序编译后的指令集 类是模板,肯定需要存在内存里面,因为实例化对象的时候需要根据这个模板来创建,那么存在内存里面,存在哪呢?? 类模板存在:全局区!
存的是:类的描述,还有所有的方法实现 每个对象都会有一个系统给我们的isa指针,但是这个指针无法直接使用,指针指向的是它所属的类的地址。 对象和类的原则:对象一定属于类。
对象调用方法,步骤其实是 先从指针变量找到对象所在堆空间地址,然后再通过这个对象里存的isa指针找到类中存的方法,再执行
*/ #import <Foundation/Foundation.h> @interface Person : NSObject{ @public
NSString *_name;
int _age;
} -(void)sayHi; @end @implementation Person //当类被加载的时候会调用这个方法
+(void)load{
NSLog(@"Person类被加载了");
} -(void)sayHi{
NSLog(@"大家好,我叫%@,今年%d岁",_name,_age);
} @end int a = ; void test(){ } @interface Dog : NSObject @end @implementation Dog //当类被加载的时候会调用这个方法
+(void)load{ NSLog(@"Dog类被加载了");
} @end int main(int argc, const char * argv[]) {
@autoreleasepool { //验证类在全局区
/*
NSLog(@"全局a的地址:%p",&a);//0x100004700 NSLog(@"类地址:%p",[Person class]); //0x100004688 NSLog(@"%p","abc"); // 0x100003b6e NSLog(@"%p",test);//0x1000013d0
*/ Person *p1 = [Person new]; Person *p2 = [Person new]; Person *p3 = [Person new]; NSLog(@"类地址:%p",[Person class]);//0x1000046e0 //因为下面的都是同一个类型。所以打印的isa地址都一样
NSLog(@"p1->isa=%p", [p1 valueForKey:@"isa"] );//0x1000046e0 NSLog(@"p2->isa=%p", [p2 valueForKey:@"isa"] );//0x1000046e0 NSLog(@"p3->isa=%p", [p3 valueForKey:@"isa"] );//0x1000046e0
Dog *js = [Dog new];
//因为下面的和上面的那些对象不是同一个类型,所以isa地址肯定不一样
NSLog(@"js->isa=%p",[js valueForKey:@"isa"]);//0x1000047f0 }
return ;
}
二、pragma的使用
/*
方法和函数弹出式窗口,里面包含了所有的方法和函数的声明列表以及实现列表,通过点击它可以方便又快速的跳转到某一个方法或函数那。 #pragma mark 分组名
作用:是在方法和函数弹出式窗口中增加分组信息,方便你快速的找到某个方法或函数。 #pragma mark - 分组名:
作用:跟上面一样,但是会增加分隔横线,这样看起来更直观。 */
#import <Foundation/Foundation.h> @interface Person : NSObject #pragma mark - 运动相关
-(void)run;
-(void)swimming;
-(void)playBasktball;
@end #pragma mark - Person实现类 @implementation Person #pragma mark - 运动实现
-(void)run{} -(void)swimming{} -(void)playBasktball{}
@end
三、对象作为方法的参数和返回值
1、对象作为方法的参数
/*
有参数的方法:
定义语法: -(void)方法名:(参数类型)参数1 方法名2:(参数类型)参数2;
把对象作为方法的参数:
语法:--(void)方法名:(类名 *)参数1; 调用:
[对象 方法名:对象]
例: [d displayPerson:p1]; 注意:
C以前分值传递和引用传递,现在OC也是一样。
所以也就是说,你把int char float 结构体变量 等等传给方法都是值传递。
值传递:在方法内改变了形参的值,外面的实参不会改变。
传递对象:是引用传递。
引用传递:在方法内改变了形参的值,外面的实参也会发生改变。 */ #import <Foundation/Foundation.h> #pragma mark - Person类
@interface Person : NSObject{
@public
NSString *_name;
int _age;
} @end @implementation Person @end #pragma mark - Display类
@interface Display : NSObject -(void)displayPerson:(Person *)p; //相当于这个方法需要传入一个Person对象 -(void)changePerson:(Person *)p;//改变Person对象的属性 -(void)changeInt:(int)number; @end @implementation Display
-(void)displayPerson:(Person *)p{ NSLog(@"p->_name=%@ p->_age=%d",p->_name,p->_age);
} -(void)changePerson:(Person *)p{
p->_name = @"习大大";
p->_age = ;
} @end #pragma mark - Main函数
int main(int argc, const char * argv[]) {
@autoreleasepool { //实例化Display对象
Display *d = [Display new]; //把对象作为方法的参数进行输出
//实例化Person对象,名字叫p1
Person *p1 = [Person new]; p1->_name = @"周小帅";
p1->_age = ; //传进去的对象是什么,就会打印什么
[d displayPerson:p1];//周小帅 16
}
return ;
}
2、对象作为方法的返回值
/*
方法定义:
-(返回值类型)方法名:参数列表;
-(int)
-(char)
-(int *)
-(struct student)
-(Person *) //相当于要返回一个Person类的对象
语法:
-(类名 *)方法名:参数列表 -(Person *)creatPerson; //返回一个Person对象
*/
#import <Foundation/Foundation.h> #pragma mark - Person类
@interface Person : NSObject{ @public
NSString *_name;
int _age;
} -(void)sayHi; @end @implementation Person -(void)sayHi{ NSLog(@"大家好,我叫%@,今年%d",_name,_age);
} @end #pragma mark - PersonFactory类 @interface PersonFactory : NSObject /**
* 这个方法返回一个Person对象
*/
-(Person *)creatPerson; @end @implementation PersonFactory -(Person *)creatPerson{
//new关键字无论何时都会开辟新的堆空间(新的对象)
Person *p = [Person new];
p->_age = ;
p->_name = @"周帅";
return p; //你要Person对象,我的p刚好就是person对象,所以可以返回p
//所以每次返回的地址都不一样
} @end
int main(int argc, const char * argv[]) {
@autoreleasepool {
PersonFactory *pf = [PersonFactory new];
//creatPerson里面方法用了new,所以每次返回的都是新的对象
//zs是一个Person对象,地址比如说是:0x11
Person *zs = [pf creatPerson];
//然后打印的是0x11地址里面存的成员数据,因为没有改过,所以打印的还是原来方法内改的值
NSLog(@"zs->name=%@ zs->age=%d",zs->_name,zs->_age);//周帅 16
//ls也一个Person对象,地址比如说是:0x12
Person *ls = [pf creatPerson];
//然后打印的是0x12地址里面存的成员数据,因为没有改过,所以打印的还是原来方法内改的值
NSLog(@"ls->name=%@ ls->age=%d",ls->_name,ls->_age);//周帅 16
//改的是0x11里面的数据
zs->_name = @"苍苍苍";
zs->_age = ;
//因为ls指向的0x12没改,所以打印的还是原数据
NSLog(@"ls->name=%@ ls->age=%d",ls->_name,ls->_age);//周帅 16
//因为zs指向的0x11里面的改了,所以打印的是改后的数据
NSLog(@"zs->name=%@ zs->age=%d",zs->_name,zs->_age);//苍苍苍 15
}
return ;
}
四、结构体作为类的成员
typedef struct {
    int year;
    int month;
    int day;
}myDate;
@interface Person : NSObject{
    @public
    NSString *_name;
    int _age;
    BOOL _gender;
    //出生年月日
    myDate _birthDay;
    //人可以养一条宠物
    Dog *_chongwu; //代表是Dog对象类型
}
/**
 *  说自己生日的
 */
-(void)sayMyBirthDay;
@end
@implementation Person
-(void)sayMyBirthDay{
    NSLog(@"我出生于%d年%d月%d日",_birthDay.year, _birthDay.month,_birthDay.day);
    _chongwu->_color = @"黄色";
}
@end
/*
 结构体也可以作为类的成员。
 本身类的成员属性的定义语法就是 : 类型  成员变量名;
    所以只要符合这个语法的都行!
    所以换句话来说,所有只要是类型的东西,都可以作为成员属性
 结构体作为对象的成员:
    在对象内部:成员名.成员  例:_birthDay.year
    在外部:对象名->成员名.成员  例: p->_birthDay.year
*/
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *p = [Person new];
        p->_age = ;
//        p->_birthDay.year = 1998;
//        p->_birthDay.month = 2;
//        p->_birthDay.day = 3;
        //一次性赋值,需要强转,右边的小括号里面必须加这个结构体的类型
        p->_birthDay = (myDate){,,};
        //实例化某个对象属性
        p->_chongwu = [Dog new];
        [p sayMyBirthDay];
        NSLog(@"出生于哪年%d",p->_birthDay.year);
        //外部访问某一个属性(这个属性又是一个对象)的时候的赋值
        p->_chongwu->_color = @"红色";
        NSLog(@"养了条宠物,毛色是%@",p->_chongwu->_color);
    }
    return ;
}
五、多文件开发
/*
c语言中有多文件开发,oc中肯定也有。
多文件开发的原因:
1.我们的类代码太多,写在一个文件里面不利于观察。
2.项目是多个人一起开发的,如果写在一个文件里面不利于同时开发。
注意: 写好模块后,一定只能导入.h文件,不能导入.m文件。 多文件开发添加文件方式:鼠标右键,选择New File ,然后在选择Cocoa Class ,第一栏填名称,第二栏是表示继承哪里,一般情况下不需要修改,会自动穿件oc的头文件和.m文件。
*/
六、结构体与类的区别、函数与方法的区别
/*
结构体与类的区别:
1.语法区别。
2.结构体里面不能包含行为(方法、函数),类可以。
3.结构体成员不能写访问修饰符,但是类可以。
4.结构体里面不能有类的对象作为成员,但是类可以有结构体作为成员。
5.结构体数据保存在栈,对象数据保存在堆。
6.结构体是面向过程的思维产物,类是面向对象的思维产物。 函数与方法的区别:
1.语法不同。
2.函数可以直接调用,方法必须通过对象。
3.函数的声明可以写在任意位置,不包括属性列表的大括号里面。方法的声明只能写在@interface和@end之间,不包括属性列表的大括号里面。
4.函数的实现可以写在除了函数内的其他所有位置(不要写在@interface和@end之间),不包括属性列表的大括号里面,方法的实现只能写在@implementation和@end之间。
5.函数是面向过程的思维,方法是面向对象的思维。
*/
七、NSString的略详细介绍
/*
 NSString 是OC中的字符串类型
    用法:
        NSString *str = @"字符串";
    1.NSString也是一个对象,所以也可以通过new来创建
    2.NSString按格式化组成一个字符串
                [NSString stringWithFormat:@"格式化字符串",值列表];
            例: NSString *str = [NSString stringWithFormat:@"哈哈,今年%d岁",16];
    3.OC中比较两个字符串是否相等:
        C语言:strcmp(字符串1,字符串2) == 0 代表相等;
        OC:[ OC字符串1 isEqualToString:OC字符串2]; 这个方法有一个BOOL类型的返回值,如果相等返回YES,否则返回NO
        例:[str1 isEqualToString:str2]
        注意:也可以直接把这个方法调用写在if括号里面判断
    4.OC字符串怎么计算实际个数??(重点)
        C语言:strlen(字符串);  计算实际占用的字节数
        OC语言:[OC字符串 length]; 返回这个OC字符串的实际个数
        例:[str length];
*/
#import <Foundation/Foundation.h>
@interface Person : NSObject{
    @public
    int _age;
}
@end
@implementation Person
@end
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        //不用这种写法,因为这种对象主要是用来表示一个字符串
//        NSString *str = [NSString new];
//        str = @"字符串";
        //直接这么用就行
//        NSString *str = @"字符串";
//
//        NSLog(@"%@",str);
          //格式化字符串//        NSString *str = [NSString stringWithFormat:@"哈哈,今年%d岁",16];
//
//        NSLog(@"%@",str);
        //判断两个字符串是否相等
        /*
        NSString *str1 = @"哈哈";
        NSString *str2 = @"哈哈";
        BOOL res = [str1 isEqualToString:str2];
        if (res) {
            NSLog(@"相等");
        }else{
            NSLog(@"不相等");
        }
        */
        /*
        BOOL res = [@"哈哈" isEqualToString:@"哈哈"];
        if (res) {
            NSLog(@"相等");
        }else{
            NSLog(@"不相等");
        }
        */
        //获得OC字符串的实际个数
        NSString *str = @"abcd 哈^";
        unsigned long length  = [str length];
        NSLog(@"%lu",length);//7个 空格、符号等等都算
        unsigned long length2  = [@"呵呵呵" length];
        NSLog(@"%lu",length2);//3个
    }
    return ;
}
oc语言学习之基础知识点介绍(二):类和对象的进一步介绍的更多相关文章
- oc语言学习之基础知识点介绍(五):OC进阶
		
一.点语法介绍 /* 以前封装后,要给属性赋值,必须调用方法 这样做,有两个缺点: 1.代码量多,调用方法要写的东西多. 2.看起来并不像是给属性赋值,也不像取值. 我们用点语法就可以更好的解决! 点 ...
 - oc语言学习之基础知识点介绍(四):方法的重写、多态以及self、super的介绍
		
一.方法重写 /* 重写:当子类继承了父类的方法时,如果觉得父类的方法不适合,那么可以对这个方法进行重新实现,那么这个就重写. 注意:也就是说,一定只能发生在父类和子类关系中. 然后是子类重新实现父类 ...
 - oc语言学习之基础知识点介绍(一):OC介绍
		
一.第一个OC程序 #import <Foundation/Foundation.h> //导入头文件 int main(int argc, const char * argv[]) ...
 - oc语言学习之基础知识点介绍(三):类方法、封装以及继承的介绍
		
一.类方法的使用 /* 像我们之前学的方法,必须先实例化这个类的对象才能调用这个方法,类方法不用实例化对象,直接调用这个方法. 之前学的方法调用的语法: [对象名 方法名]; //对象方法 类方法: ...
 - c语言学习之基础知识点介绍(二):格式化控制符和变量的补充
		
上节简单介绍了c语言中的一些基础知识点,本节将对之前介绍的不够详细的知识点进行补充. 格式化控制符的消息介绍: %d的其他控制符: 1.%md:m代表这个整数位占用多少位,m是一个整数.实际数字不足的 ...
 - c语言学习之基础知识点介绍(三):scanf函数
		
本节继续介绍c语言的基础知识点. scanf函数:用来接收用户输入的数据. 语法:scanf("格式化控制符",地址列表); 取地址要用到取地址符:&(shift+7) 例 ...
 - c语言学习之基础知识点介绍(十):数组
		
本节主要介绍数组. 一.数组 /* 数组:一个变量可以存n个变量. 语法:类型 数组名[长度(正整数)]; 例如:int score[5];//定义了一个int类型的数组,长度为5,可以保存5个数据. ...
 - c语言学习之基础知识点介绍(六):if和switch结构
		
本节主要说c语言中的分支结构. c语言中分支结构有两大类:一种是if,一种是switch. 一.if结构 //if结构,语法: //第一种: if(表达式){ //语句块 } //第二种: if(表达 ...
 - c语言学习之基础知识点介绍(二十):预处理指令
		
一.预处理指令的介绍 预处理命令:在编译之前触发的一系列操作(命令)就叫预处理命令. 特点:以#开头,不要加分号. #include: 文件包含指令 把指定文件的内容复制到相应的位置 #define: ...
 
随机推荐
- ubuntu下一次网络流量危机
			
为了便于团队合作,公司局域网搭建了一台服务器,安装了ubuntu 13.04. 一直相安无事.直到今天上午. 突然的大流量,让整个局域网网速慢下来,网页都打不开. 差不多一个小时都是这样,我还以为是公 ...
 - dynamic调用时报RuntimeBinderException:“object”未包含“xxx”的定义 错误
			
情况如下:两个项目项目A命名空间 Test.PA 匿名类型所在 项目B命名空间 Test.PB 在Test.PB 中通过dynamic关键字调用Test.PA中匿名类型时报上述错误 解决办法 在项 ...
 - UI进阶 数据处理之文件读写
			
目录: 1-------沙盒机制(SandBox) 2-------简单对象的读写(I/O)操作 3-------复杂对象的读写(I/O)操作 一.沙盒机制(SandBox) 什么是沙盒:每个iOS应 ...
 - PHP魔术变量总结
			
php手册里面的解释 __FUNCTION__ returns only the name of the function 返回的仅仅是函数的名称 __METHOD__ returns t ...
 - ASP.Net 使用SqlBulkCopy批量插入
			
批量插入,以前我的做法是生成一堆insert into的sql语句,然后用程序一次值行,来实现. 今天看到了ASP.Net里可以使用DataTable,先将数据写入到DataTable中,然后使用Sq ...
 - MySQL 索引、视图、DML
			
1.索引 索引是存放在模式(schema)中的一个数据库对象,索引的作用就是提高对表的检索查询速度, 索引是通过快速访问的方法来进行快速定位数据,从而减少了对磁盘的读写操作. 索引是数据库的一个对象, ...
 - ASP.NET 学习的总结
			
应用程序域 使用.Net建立的可执行程序*.exe,并没有直接承载到进程当中,而是承载到应用程序域(AppDomain)当中.应用程序域是.Net引入的一个新概念,它比进程所占用的资源要少,可以被看做 ...
 - .NET加密配置文件connectionStrings节点
			
具体的可以参考petshop源码程序. 加密前: <connectionStrings> <add name="SQLProfileConnString" con ...
 - MySQL5日期类型DATETIME和TIMESTAMP相关问题详解
			
MySQL5日期类型DATETIME和TIMESTAMP相关问题详解 MySQL5的日期类型有三种:DATETIME.DATE和TIMESTAMP,除了DATE用来表示一个不带时分秒的是日期,另外两个 ...
 - 转载:iPhone 6 Plus 屏幕宽度问题 375 vs 414
			
首先看一张比较简单明了的 iPhone 6 与 iPhone 6 Plus 对比图,来自 PaintCode 的<The Ultimate Guide To iPhone Resolutions ...