--------------------------------------------IOS期待与您交流!--------------------------------------------
1、没有使用点语法的情况
此时我们使用setter和getter方法来访问对象的成员变量
#import <Foundation/Foundation.h> @interface Person : NSObject { int _age; } - (void)setAge:(int)age; - (int)age; @end @implementation Person - (void)setAge:(int)age { NSLog(@"调用了setAge方法"); _age = age; } - (int)age { NSLog(@"调用了age方法"); return _age; } @end int main() { // 没有使用点语法的时候 Person *p = [Person new]; [p setAge:20]; int age = [p age]; NSLog(@"年龄是:%d", age); return 0; }输出结果:
2014-03-19 20:15:13.476 Test[470:303]调用了setAge方法
2014-03-19 20:15:13.477 Test[470:303]调用了age方法
2014-03-19 20:15:13.478 Test[470:303]年龄是:20
2、使用了点语法的情况
使代码更简洁了, 本质是方法调用
#import <Foundation/Foundation.h> // Person方法的声明和实现和上面一样 int main() { // 使用点语法的时候 Person *p = [Person new]; p.age = 20; // 本质是 -> [p setAge:20]; int age = p.age; // 本质是 -> int age = [p age]; NSLog(@"年龄是:%d", age); return 0; }输出结果:
2014-03-19 20:15:13.476 Test[470:303] 调用了setAge方法
2014-03-19 20:15:13.477 Test[470:303] 调用了age方法
2014-03-19 20:15:13.478 Test[470:303] 年龄是:20
3、注意
- (void)setAge:(int)age { // 相当于 [self setAge:age],会引发死循环 self.age = age; } - (int)age { // 相当于 [self age],会引发死循环 return self.age; }
public:在任何地方都能直接访问对象的成员变量
protected:可在当前类及其子类对象中直接访问对象的成员变量(默认的)
private:只能在当前类中直接访问对象的成员变量
package:同一框架中能直接访问对象的成员变量
1、以前的代码方式
@interface Person : NSObject { int _age; } - (void)setAge:(int)age; - (int)age; @end @implementation Person - (void)setAge:(int)age { _age = age; } - (int)age { return _age; } @end2、使用了@property和@synthesize
下面代码和上面是等效的
@interface Person : NSObject @property int age; @end @implementation Person @synthesize age = _age; @end3、只使用了@property
下面代码和上面是等效的
@interface Person : NSObject @property int age; @end @implementation Person @end4、总结
1-> 只用@property时,会产生3个效果(以@property int 为例)
1 生成 _age 成员变量(private的成员变量)
2 生成 age 的 setter 和 getter 方法的声明
3 生成 age 的 setter 和 getter 方法的声明
2-> 使用@property和@synthesize时,和上面的效果基本相同,不同在于@synthesize可以指定生成的成员变量的名称。
如
@interface Person : NSObject @property int age; @end @implementation Person @synthesize age = hello; @end
就会等价于
@interface Person : NSObject { int hello; } - (void)setAge:(int)age; - (int)age; @end @implementation Person - (void)setAge:(int)age { hello = age; } - (int)age { return hello; } @end使用@synthesize时,推荐使用_age,这样更符合约定
5、此外
只有使用了@property ,才会自动生成private的_age。使用@synthesize 用来改变@property 生成的成员变量名。
如果自己只实现了setter 方法,会自动生成getter 方法和带下划线的成员变量(_age)
如果自己只实现了getter 方法,会自动生成setter 方法和带下划线的成员变量(_age)
如果自己实现了setter 方法和getter 方法,就不会自动生成成员变量(_age),需要我们手动生成
1、new方法
我们可以通过new 方法来生成一个对象
Person *p = [Person new];其实new 是分两步来生成对象的
* 调用+alloc 方法来给对象分配内存空间
* 调用-init 方法给对象的成员变量初始化成默认的值
缺点:不能在创建对象的同时进行一些必要的初始化
2、alloc 和 init 方法
重写构造方法的目的:为了让对象一创建出来,成员变量就由一些默认的值
@interface Person : NSObject @property int age; @end @implementation Person // 需要重写init 方法来满足自己的初始化要求 - (id)init { // 必须先调用父类的构造方法对父类的变量进行初始化 if (self = [super init]) { _age = 20; } return self; } @end int main() { Person *p = [[Person alloc] init]; // 和 Person *p = [Person new]; 一样的效果 NSLog(@"年龄是:%d", p.age); return 0; }输出:
2014-03-19 21:20:29.860 Test[644:303]年龄是:20
3、自定义init 方法(自定义构造方法)
@interface Person : NSObject @property int age; @end @implementation Person - (id)initWithAge:(int)age { if (self = [super init]) { _age = age; } return self; } @endint main() { Person *p = [[Person alloc] initWithAge:24]; NSLog(@"年龄是:%d", p.age); return 0; }输出:2014-03-19 21:25:55.821 Test[656:303]年龄是:24
作用:在不改变类的基础上增加一些方法
类名:类名 (分类名)
分类名一般是模块名
如想为Person类增加一个添加一个分类LXZ
Person+LXZ.h
#import "Person.h" @interface Person (LXZ) - (void)study; @endPerson+LXZ.m
#import "Person+LXZ.h" @implementation Person (LXZ) - (void)study { NSLog(@"lxz study"); } @endmain.m
#import <Foundation/Foundation.h> #import "Person.h" #import "Person+LXZ.h" int main() { Person *p = [[Person alloc] init]; [p study]; return 0; }输出:
2014-03-19 21:58:17.997 OCTest[841:303] lxz study
注意
1 分类只能增加方法,不能增加成员变量
2 分类方法中可以访问原来类中的成员变量
3 分类可以重新实现原来类中得方法,这会覆盖原来类中的方法,使原来类中的方法失效
4 方法调用优先级:分类(最后被编译的分类) -> 原来类
在OC中,对象或类每当调用一个方法时,会把方法包装成一个SEL的数据类型,然后去类对象中找对应的SEL(类对象中有该类的所有方法的SEL,每个方法对应一个SEL)。若找到,则调用相应的方法,若没找到,则报错。
以上面的 Person 类为例,看看调用age的getter方法的方式有哪些
方式一(隐式的使用了SEL)
[p age];方式二(显式的使用了SEL)
[p performSelector:@selector(age)];方式三(显示的使用了SEL)
SEL sel = NSSelectorFromString(@"age"); [p performSelector:sel];
--------------------------------------------IOS期待与您交流!--------------------------------------------
详细请查看:http://edu.csdn.net