黑马程序员-@property,@synthesize使用细节和id
一、@property和@synthesize 关键字以及使用细节
这两个关键字是编译器的特性,帮助我们有效的减少不必要代码的书写。
1.@property可以自动生成某个成员变量的setter和getter方法声明
1 #import <Foundation/Foundation.h> 2 3 @interface Person : NSObject 4 { 5 int _age; 6 // int age; 7 int _height; 8 double _weight; 9 NSString *_name; 10 } 11 12 // @property:可以自动生成某个成员变量的setter和getter声明 13 @property int age; 14 //- (void)setAge:(int)age; 15 //- (int)age; 16 17 @property int height; 18 //- (void)setHeight:(int)height; 19 //- (int)height; 20 21 - (void)test; 22 23 @property double weight; 24 25 @property NSString *name; 26 27 @end
这里注意不可以写成@property int _age;这样写的话会默认声明: - (void)setAge:(int)_age;- (int)_age; 就无法调用p.age或者[p setAge:10];只能这样调用p._age;或者[p set_age:10];
而@synthesize可以自动生成某个成员变量的setter和getter方法
1 #import "Person.h" 2 3 @implementation Person 4 5 // @synthesize自动生成age的setter和getter实现,并且会访问_age这个成员变量 6 @synthesize age = _age; 7 8 @synthesize height = _height; 9 10 @synthesize weight = _weight, name = _name; 11 12 @end
这里注意@synthesize age = _age;不可以写成@synthesize age = age;或者@synthesize age;这样写的话会自动访问age这个变量而不是_age这个成员变量(假设@interface中有声明age这个变量)
2.其实还有更简便的方法,@interface中去掉成员变量的声明。但是注意如果@interface中没有声明成员变量,那么会自动生成@private类型成员变量。如果想要成员变量为@protected类型的,方便子类访问,那么只能在@interfae中声明了。
1 #import <Foundation/Foundation.h> 2 3 @interface Car : NSObject 4 { 5 //int _speed; 6 //int _wheels; 7 } 8 @property int speed; 9 @property int wheels; 10 11 //@property int speed, wheels; 12 - (void)test; 13 @end
1 #import "Car.h" 2 3 @implementation Car 4 //@synthesize speed = _speed, wheels = _wheels; 5 // 会访问_speed这个成员变量,如果不存在,就会自动生成@private类型的_speed变量 6 @synthesize speed = _speed; 7 @synthesize wheels = _wheels; 8 9 - (void)test 10 { 11 NSLog(@"速度=%d", _speed); 12 } 13 14 @end
3.在Xcode4.4以后,@proterty关键字会自动声明和实现成员变量的setter和getter方法,无需@synthesize关键字
1 #import <Foundation/Foundation.h> 2 3 @interface Dog : NSObject 4 @property int age; 5 @end
1 #import "Dog.h" 2 3 @implementation Dog 4 5 @end
这里要注意几点:
1>如果手动实现了set方法,那么编译器就只生成get方法和成员变量;
2>如果手动实现了get方法,那么编译器就只生成set方法和成员变量;
3>如果set和get方法都是手动实现的,那么编译器将不会生成成员变量。
二、id
>万能指针,能够指向任何OC对象,相当于NSObject *
>id类型的定义:
1 typedef struct objc_object 2 { 3 Class isa; 4 } *id;
>注意id后面不要加*
id p = [person new];
>局限性:调用一个不存在的方法,编译器会立马报错。
1 #import <Foundation/Foundation.h> 2 3 @interface Person : NSObject 4 @property int age; 5 @property id obj; 6 @end
1 #import "Person.h" 2 3 @implementation Person 4 5 @end
1 #import <Foundation/Foundation.h> 2 #import "Person.h" 3 4 void test(id d) 5 { 6 7 } 8 9 int main(int argc, const char * argv[]) 10 { 11 12 @autoreleasepool { 13 Person *p = [Person new]; 14 NSObject *o = [Person new]; 15 // id == NSObject * 16 // 万能指针,能指向\操作任何OC对象 17 id d = [Person new]; 18 19 [d setAge:10]; 20 // 可以传任何对象 21 [d setObj:@"321423432"]; 22 23 NSLog(@"%d", [d age]); 24 } 25 return 0; 26 }