上一篇:关于runtime的知识点整理
二. 关于成员变量,实例变量,@public,@private,@protected,@package,@property,@synthesize,@dynamic
成员变量:
代码中的变量,包含实例变量和基础数据类型,无需与外界接触;
实例变量:
由类定义的实例化的变量(不包含基础数据类型,如int
,double
,float
);
@public:
在任何地方都能直接访问对象的成员变量;
@private:
只能在当前类及其子类的对象方法中直接访问,如果子类要访问需要调用父类的setter
、getter
方法;
@protected:
可以在当前类的对象方法中直接访问(系统默认下是用它来修饰的);
@package:
在同一个包下就可以直接访问,比如说在同一个框架下;
@property:
a. 是声明属性的语法,可以快速方便的为成员变量创建存取器,允许我们通过点语法使用存取器
(存取器:指用于获取和设置成员变量的方法。用于获取成员变量值的存取器是getter
,用于设置实例变量的存取器是setter
),可与外界接触;
b. 使用@property就不必单独声明成员变量了,因为在没有显式提供成员变量声明的前提下,系统会自动帮你生成成员变量;
c. 当我们同时重写了setter和getter方法时,系统会报错,其解决办法:在.m文件中使用@synthesize
(原因:同时重写时。系统就不会自动生成setter和getter方法,成员变量也不就不会生成了,默认的@synthesize var=_var
就会失效,所以会报Use of undeclared identifier '_var'
的错误)。
@synthesize:
a. @synthesize
是为属性添加一个成员变量名,或者说别名。同时会为该属性生成 setter/getter
方法。
b. 如果某属性已经在某处实现了自己的 setter/getter
,可以使用 @dynamic
来阻止 @synthesize
自动生成新的setter/getter
覆盖。
c. 当在protocol
中声明并实现属性时。协议中声明的属性不会自动生成setter和getter
,需要使用@synthesize
生成setter和getter
。 [UIApplicationDelegate window]
就是个典型的例子。
d. @property
有两个对应的词,一个是 @synthesize
,一个是 @dynamic
。如果 @synthesize和 @dynamic
都没写,那么默认的就是@syntheszie var = _var
;
@dynmic:
@dynamic
告诉编译器:属性的 setter 与 getter
方法由用户自己实现,不自动生成。(当然对于 readonly
的属性只需提供getter
即可)。假如一个属性被声明为 @dynamic var
,然后你没有提供 @setter
方法和 @getter
方法。编译的时候没问题,但是当程序运行到 instance.var = someVar
,由于缺 setter
方法会导致程序崩溃;或者当运行到 someVar = var
时,由于缺 getter
方法同样会导致崩溃。编译时没问题,运行时才执行相应的方法,这就是所谓的动态绑定。
代码示例:
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSUInteger, SEX) {
GIRL,
BOY
};
@interface ViewController : UIViewController
{
@public NSString *name;
@private int age;
@protected SEX sex;
@package NSString *grade;
}
@end
子类中被@private
修饰的age
不能被访问
其他类中被@private
修饰的age和@protected
修饰的sex不能被访问
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic,copy) NSString *test;//系统会自动生成setter,getter方法
@end
@implementation ViewController
//在使用@property时同时重写setter和getter方法报错,解决办法使用@synthesize指定成员变量:
@synthesize test;//表明生成的成员变量是test。
- (void)viewDidLoad {
[super viewDidLoad];
}
-(void)setTest:(NSString *)test {
test = test;
}
- (NSString *)test {
return test;
}
@end