黑马程序员-点语法,成员变量作用域,@property,@synthsize和 id

来源:互联网 发布:java math.ceil 编辑:程序博客网 时间:2024/05/21 20:30

---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------

 

点语法

Person *p = [Person new];

p.age = 10;/* 点语法的本质还是方法调用,当使用点语法,编译器遇到了自动展开[p setAge:10];

而且它不是访问成员变量age(成员变量为_age),p->_age是OC里面直接访问成员变量的唯一方式

 

int a = p.age// [p age] age的get方法

判断是set还是get方法:有没有赋值,赋值是set方法

对p.age打断点测试,用左下第四个按钮 setp into跳转代码到set方法,从而验证了赋值点语法的本质是set方法。

 

- (void)setAge:(int)age

{

    //_age = age;

   

    NSLog(@"setAge:");

   

    // 会引发死循环

    //self.age = age; // [self setAge:age];

}

 

- (int)age

{

    NSLog(@"age");

    return _age;

    // 会引发死循环

    //return self.age;  //[self age];

}

成员变量的作用域

@interface Person : NSObject

{

@public

//*任何地方都可以直接访问对象成员变量(直接通过成员变量名),当然首先得有对象*/

 

@private

// 只能在当前类的对象方法中直接访问。子类虽然不能访问,但是仍然是拥有这个成员变量的。

 

@protected// 能在当前类和子类的对象方法中直接访问(不写默认就是@protected)

 

@package : 只要处在同一个框架中,就能直接访问对象的成员变量。

 

}

 

#import <Foundatition/Foundatition.h>

#import "Person.h"

int main()

{

    Person *p = [Person new];

    p->_age = 100;

    p->_height = 12;//这是private的会报错的

}

 

如果想在子类访问私有成员变量调用方法

@implementationStudent

{

    int _aa;//也可以的。但是它默认不是protected而是私有private

    //@implementation 中不能定义和@interface中同名的成员变量。

}

-(void)study

{

    [self setHeight:15];

    int h = [self height];

    -weight = 100;

}

 

关键字@property

@property 关键字可以自动生成某个成员变量的setter和getter方法的声明:

@property int age;

编译时遇到这一行,则自动扩展成下面两句:

- (void)setAge:(int)age;

- (int)age;

 

@property int _age;

//最好不要写_age,因为这样生成的不是标准的setget方法

@property int _age;

p.age = 10;//报错,生成的是下划线(void)setAge(int)_age;

 

@synthesize关键字

@synthesize关键字帮助生成成员变量的setter和getter方法的实现

#import <Foundatation/Foundatition.h>

@interface Person : NSObject

{

    int age;

    int _age;

}

@property int age;

- (void) test;

@end

 

@implementation

//自动生成age的setter和getter,并且访问_age这个成员变量

@synthsize age = _age, name = _name//还可以两个在一起;

- (void) test

{

    NSLog(@"age=%d, _age=%d",age, _age);

}

@end

int main()

{

    Person *p = [Person new];

    [p setAge:10];

    [p test];

}

 

需要注意的地方

 

#import <Foundation/Foundation.h>

@interface Car : NSObject

{

   /*@protected

  int _age;

  如果不想自动生成@private就在这里添加个@protected

    */

    int _wheels;

    int _speed;

}

 

//很少有写在一起的@property int wheels,speed;//都是int型

@property int wheels;

@property int speed;

 

@end

 

@implementation

 

//@synthsize wheels = _wheels,speed = _speed;

//会访问下划线_speed这个成员变量,如果不存在,就会自动生成@private类型成员变量

@synthsize wheels = _wheels;

@synthsize speed = _speed;

 

@synthsize age;

//如果不写等号后面的,就是访问同名成员变量也就是age而不是_age;

//如果没有age,就会自动生成@private类型的age变量

 

- (void)test

{

    NSLog(@"速度=%d", _speed);

}

@end

 

int main()

{

    Car *c = [Car new];

    c.speed = 100;

    [c test];

    NSLog(@"%d", c.speed);

}

@property只能写在@interface  @end中,@synthesize只能写在@implementation   @end中,自从xcode 4.4后,@property就独揽了@property和@synthesize的功能.

原则:get和set方法同变量一样,如果自己定义了,那么就使用已经定义的,如果没有定义,那么就自动生成一个。

手动实现:

1)如果手动实现了set方法,那么编译器就只生成get方法和成员变量;

2)如果手动实现了get方法,那么编译器就只生成set方法和成员变量;

3)如果set和get方法都是手动实现的,那么编译器将不会生成成员变量。

 

Id类型

 

 

 #import <Foundatation/Foundatition.h>

@interface Person : NSObject

{

    int _age; 

}

@property int age;

@property id obj;

 

void test(id d)

{

    任何对象都能传递进来。

}

 

@end

 

@implementation

@end

int main ()

{

    Person *p = [Person new];

   

  //id  == NSObject *

    id d = [Person new];//万能指针,能指向\操作任何OC对象

    [d setAge:10];

 

    [d setObj:@"daf4568asdf"];//任意对象都可以

    NSLog(@"%d",[d age]);

}

id 类型的定义

Typedef struct objc object{

Class isa;

} *id;

注意:在id的定义中,已经包好了*号。Id指针只能指向os的对象。

只要求掌握两点就完事了: 1. id == NSObject *

2. id后面不要加 *

               

 

---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------详细请查看:www.itheima.com
0 0
原创粉丝点击