一.点语法
点语法的本质是方法调用,并不是访问成员变量,编译器看到点语法有两种处理
1 .是赋值,赋值的就是展开为set方法
2. 不是赋值:展开为set方法
使用示例:
Person类的声明与实现:
1 #import <Foundation/Foundation.h> 2 3 @interface Person : NSObject 4 @property (nonatomic,assign) int age; 5 @end
1 #import "Person.h" 2 3 @implementation Person 4 5 @end
点语法的测试:
1 int main(int argc, const char * argv[]) 2 { 3 Person *p = [Person new]; 4 // 点语法的本质是方法调用,并不是访问成员变量 5 6 p.age = 10; // 相当于[p setAge:10] 7 8 int a = p.age; //相当于 [p age] 9 NSLog(@"a = %d ",a); 10 return 0; 11 }
点语法[1325:106300] a = 10
二. OC成员变量的作用域
@public :任何地方访问
@private :只能在当前类的对象方法中直接访问
@protected :能在当前类和子类中直接访问(默认)
@package :只要处于同一个框架中就能直接访问对象成员变量
三. @property 与 @synthesize
由于类的封装性,要求我们要自己给外部提供一些方法去访问我们的成员变量,这方法在OC中就是set或get方法,但由于set或get方法格式固定,且如果成员变量过多,写起来很花费时间且没有太大的帮助,于是就有了下面的两个关键字帮助我们完成set和get方法:
1)@property
1. 用在@interface 中
2. 用来自动生成setter和getter
3. @property int
age;就可以替换下面两行
1 - (void)setAage:(int)age; 2 - (int)age;
1)@synthesize
1> 用在@implementation中
2> 用来自动生成自动生成set和get方法实现
3> 用@synthesize age = _age;就可以替代
1 - (int)age 2 { 3 return _age; 4 } 5 - (void)setAge:(int)age 6 { 7 _age = age; 8 }
说明:xcode4.几以后@property独揽了@synthesize功能即@property可同时生成 set和get方法的声明和实现,成员变量都不用声明,缺点是成员变量私有,要自己加成员变量 protect
@property使用示例:
Person类的声明
1 #import <Foundation/Foundation.h> 2 3 @interface Person : NSObject 4 5 // @property 可自动生成某个成员的set和get声明 6 // 成员变量名不能加 _ 7 // 如果成员变量不存在,则会自动生成 private类型 8 @property int age; 9 //- (void)setAage:(int)age; 10 //- (int)age; 11 @end
测试:
1 #import <Foundation/Foundation.h> 2 #import "Person.h" 3 int main(int argc, const char * argv[]) 4 { 5 Person *p = [Person new]; 6 /* 点语法的使用 */ 7 p.age = 5; 8 NSLog(@"p.age %d ",p.age); 9 10 return 0; 11 }
set[762:52529] p.age 5
手动实现的情况
1)若手动实现了set方法,编译器只会自动生成get 方法
2)若手动实现了get方法,编译器只会自动生成set 方法
3)若手动同时实现了set方法和get方法,编译器不会自动生成不存在的成员变量
原则: 你有的我就不帮你实现,你实现了get我就只生成set;如果你实现了set 和get 则不会生
成成员变量。
四.id 简介:
1. 万能指针,指向任何OC对象,相当于NSObject *
2. id 类型定义
1 typedef struct obj object{ 2 Class isa; 3 }*id;
使用示例:
id p = [Person new];
局限性:调用一个不存在的方法,编译器马上报错。
五.OC构造方法:
1.什么是构造方法,构造方法是用来干什么的,为什么要有构造方法?
构造方法是用来初始化对象的方法,以- 开头,由于使用new方法创建的对象,对象的成员的初始值都为0,这在开发中很不方便,经常要在创建对象时就初始化好一些属性的值,所以使用这个构造方法可以满足这个需求。
2.使用系统自带的new创建对象的过程:
[Person new];
完整的创建一个可用对象,new做什么事情,调用两个方法
1.分配存储空间(一个对象)+alloc
2.初始化 -init 方法完成初始化,这过程通常是将成员的属性设置为0。
3.不使用new,自己创建对象的方法:
1 /* 1. 调用 +alloc 分配存储空间 */ 2 //Person *p1 = [Person alloc]; 3 4 /* 2. 调用 - init进行初始化 */ 5 //Person *p2 = [p1 init]; 6 7 //直接一句话搞定 开发中常用,初始化自己的值 8 Person *p3 = [[Person alloc] init];
现有一个需求:每个Person对象创建出来,他的_age都是10;
思路一: 重写 -init 方法:重写-init 方法示例:
Person类的定义
1 #import <Foundation/Foundation.h> 2 3 @interface Person : NSObject 4 5 @property int age; 6 7 @end
1 @implementation Person 2 3 /* 重写 -init 方法 */ 4 - (id)init 5 { 6 // 1.一定要调用super的init方法:初始化父类中声明的一些成员变量 7 8 // 2.如果对象初始化成功,才有必要进行接下来的初始化 9 // 为保证初始化之后返回的是正确的 10 if (self = [super init]) 11 {// 初始化成功 12 _age = 10; 13 } 14 15 // 3. 返回一个已经初始化完毕的对象 16 return self; 17 } 18 19 @end
2 { 3 /* 需求每个Person对象创建出来,他的_age都是10 */ 4 // Person *p = [[Person alloc] init]; 5 NSLog(@"p age %d",p.age,); 6 return 0; 7 }
2015-03-23 14:09:43.375 构造方法[917:81284] p age 10
思路二: 自定义构造方法
自定义构造方法:两部分声明和实现
自定义构造方法规范:
1.一定是对象方法
2.返回值是id类型
3.方法名以init 开头
Person类的声明:自定义构造方法用户设置名字和年龄
1 #import <Foundation/Foundation.h> 2 3 @interface Person : NSObject 4 { 5 NSString *_name; 6 int _age; 7 } 8 @property NSString *name; 9 @property int age; 10 11 // 自定义构造方法:两部分 声明和实现 12 /* 13 自定义构造方法规范: 14 1.一定是对象方法 15 2.返回值是id类型 16 3.方法名以init 开头 17 */ 18 - (id)initWithName:(NSString *)name andAge:(int)age; 19 @end
1 #import "Person.h" 2 3 @implementation Person 4 - (id)initWithName:(NSString *)name andAge:(int)age 5 { 6 /* 无论自己写还是改写 都必须执行父类初始化 */ 7 if(self = [super init]) 8 { 9 _name = name; 10 _age = age; 11 } 12 return self; 13 } 14 @end
1 #import "Person.h" 2 #import "Student.h" 3 int main() 4 { 5 /* 使用自定义构造方法初始化person对象的名字和年龄*/ 6 Person *p = [[Person alloc] initWithName:@"mike" andAge:18]; 7 NSLog(@"name %@ age %d",p.name,p.age); 8 return 0; 9 }
2015-03-23 14:20:15.727 自定义构造方法[966:85096] name mike age 18
总结:构造方法就是用来初始化成员变量的,成员变量属于父类就在父类中初始化。