标签:
/* 内存分区: 栈:局部变量 堆:程序员自己写代码申请开辟的 程序员自己维护,编译器现在帮我们自动优化了,它在合适的给我们加上了释放空间的语句,所以我们现在写的对象不会造成内存泄露 全局区:所有的全局变量和静态变量 常量区:所有的常量 代码区:程序编译后的指令集 类是模板,肯定需要存在内存里面,因为实例化对象的时候需要根据这个模板来创建,那么存在内存里面,存在哪呢?? 类模板存在:全局区! 存的是:类的描述,还有所有的方法实现 每个对象都会有一个系统给我们的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 = 10; 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 0; }
/* 方法和函数弹出式窗口,里面包含了所有的方法和函数的声明列表以及实现列表,通过点击它可以方便又快速的跳转到某一个方法或函数那。 #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 = 50; } @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 = 16; //传进去的对象是什么,就会打印什么 [d displayPerson:p1];//周小帅 16 } return 0; }
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 = 16; 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 = 15; //因为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 0; }
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 = 16; // p->_birthDay.year = 1998; // p->_birthDay.month = 2; // p->_birthDay.day = 3; //一次性赋值,需要强转,右边的小括号里面必须加这个结构体的类型 p->_birthDay = (myDate){1998,12,3}; //实例化某个对象属性 p->_chongwu = [Dog new]; [p sayMyBirthDay]; NSLog(@"出生于哪年%d",p->_birthDay.year); //外部访问某一个属性(这个属性又是一个对象)的时候的赋值 p->_chongwu->_color = @"红色"; NSLog(@"养了条宠物,毛色是%@",p->_chongwu->_color); } return 0; }
/* 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 是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 0; }
标签:
原文地址:http://www.cnblogs.com/bobo-pcb/p/4972037.html