属性, 变量,@property,@synthesize,@dynamic

先说结论
  1. @property 这是开发中最长用到的.这是在声明一个属性名 每当我们使用 @property声明了一个变量 等于做了三件事 Ivar + set + get;
  2. @synthesize 可以理解为合成. 系统会自动为我们生产set + get (我认为还会为我们 声明 等号后面的 Ivar 变量)
  3. @dynamic 就是告诉系统@property做的三件事, 都不要做了.
结合代码说明

我使用runtime 对不同组合打印
1. 正常的写法

#import <objc/runtime.h>
@interface subViewController (){
    NSString *_test2;
}
@property (nonatomic, copy) NSString *test1;
@property (nonatomic, copy) NSString *test3;
@end
@implementation subViewController
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    [self getIvarName];
    [self getPropertyName];
    [self getMethodName];
}
// 打印 IvarList
- (void)getIvarName{
    unsigned int count = 0;
    Ivar *members = class_copyIvarList([self class], &count);
    for (int i = 0; i < count; i++) {
        Ivar ivar = members[i];
        const char *membername = ivar_getName(ivar);
        NSLog(@"IvarName: %s", membername);
    }
}
// 打印 PropertyList
- (void)getPropertyName{
    unsigned int count = 0;
    objc_property_t *propertys = class_copyPropertyList([self class], &count);
    for (int i = 0 ; i < count; i++) {
        objc_property_t property = propertys[i];
        const char *propertyName = property_getName( property);
        NSLog(@"PropertyName %s", propertyName);
    }


}
// 打印 MethodList
- (void)getMethodName{
    unsigned int count = 0;
    Method *members = class_copyMethodList([self class], &count);
    for (int i = 0; i < count; i ++) {
        Method mthod = members[i];
        SEL mthod_s = method_getName(mthod);
        const char *mthod_c = sel_getName(mthod_s);
        NSLog(@"method Name :%s", mthod_c); 
    }
}
@end

打印信息是

IvarName: _test2
IvarName: _test1
IvarName: _test3
PropertyName test1
PropertyName test3
method Name :test1
method Name :setTest1:
method Name :test3
method Name :setTest3:
method Name :.cxx_destruct

因为_test没有用@property 所有没有set和get方法.
从这个打印我们可以看出 @property 其实干了四件事 以test1为例:

  1. 将tist1 放入 propertyList, 2 声明_test1 并放入IvarList, 3 声明setTest1方法 4. 声明test1 get方法.

继续测试 @dynamic;
如果在 @implementation 下一行添加

@dynamic test3;

打印信息

2017-07-17 13:36:20.952 CCNetworkHelper[1552:106531] IvarName: _test2
2017-07-17 13:36:20.953 CCNetworkHelper[1552:106531] IvarName: _test1
2017-07-17 13:36:20.953 CCNetworkHelper[1552:106531] PropertyName test1
2017-07-17 13:36:20.953 CCNetworkHelper[1552:106531] PropertyName test3
2017-07-17 13:36:20.953 CCNetworkHelper[1552:106531] method Name :test1
2017-07-17 13:36:20.953 CCNetworkHelper[1552:106531] method Name :setTest1:

对比第一打印 IvarName 中少了 _test3, methodName 中少了test3的set和get方法, 说明 @dynamic test3, 系统就只干了一件事 把test3到protertyList中.

继续测试@synthesize test1 = _test1;
如果在 @implementation 下一行添加

@synthesize test1 = _test1;

打印信息

2017-07-17 13:44:26.592 CCNetworkHelper[1577:109840] IvarName: _test2
2017-07-17 13:44:26.592 CCNetworkHelper[1577:109840] IvarName: _test1
2017-07-17 13:44:26.592 CCNetworkHelper[1577:109840] IvarName: _test3
2017-07-17 13:44:26.593 CCNetworkHelper[1577:109840] PropertyName test1
2017-07-17 13:44:26.593 CCNetworkHelper[1577:109840] PropertyName test3
2017-07-17 13:44:26.593 CCNetworkHelper[1577:109840] method Name :test1
2017-07-17 13:44:26.593 CCNetworkHelper[1577:109840] method Name :setTest1:
2017-07-17 13:44:26.594 CCNetworkHelper[1577:109840] method Name :test3
2017-07-17 13:44:26.594 CCNetworkHelper[1577:109840] method Name :setTest3:
2017-07-17 13:44:26.594 CCNetworkHelper[1577:109840] method Name :.cxx_destruct

跟第一次打印的信息一样, 说明系统默认就是这么干的.


下面是来瞎搞一下.
继续测试 如果在 @implementation 下一行

@synthesize test1 = _test2;

打印信息

2017-07-17 13:46:53.143 CCNetworkHelper[1596:111809] IvarName: _test2
2017-07-17 13:46:53.143 CCNetworkHelper[1596:111809] IvarName: _test3
2017-07-17 13:46:53.143 CCNetworkHelper[1596:111809] PropertyName test1
2017-07-17 13:46:53.144 CCNetworkHelper[1596:111809] PropertyName test3
2017-07-17 13:46:53.144 CCNetworkHelper[1596:111809] method Name :test1
2017-07-17 13:46:53.144 CCNetworkHelper[1596:111809] method Name :setTest1:
2017-07-17 13:46:53.145 CCNetworkHelper[1596:111809] method Name :test3
2017-07-17 13:46:53.145 CCNetworkHelper[1596:111809] method Name :setTest3:
2017-07-17 13:46:53.145 CCNetworkHelper[1596:111809] method Name :.cxx_destruct

对比第一次打印, _test1 没了.
于是我又做了实验 在@implementation 下添加

@synthesize test1 = _test5; // _test5以前没出现过.

打印信息

2017-07-17 13:53:48.363 CCNetworkHelper[1626:115962] IvarName: _test2
2017-07-17 13:53:48.363 CCNetworkHelper[1626:115962] IvarName: _test5
2017-07-17 13:53:48.364 CCNetworkHelper[1626:115962] IvarName: _test3
2017-07-17 13:53:48.364 CCNetworkHelper[1626:115962] PropertyName test1
2017-07-17 13:53:48.364 CCNetworkHelper[1626:115962] PropertyName test3
2017-07-17 13:53:48.364 CCNetworkHelper[1626:115962] method Name :test1
2017-07-17 13:53:48.364 CCNetworkHelper[1626:115962] method Name :setTest1:
2017-07-17 13:53:48.365 CCNetworkHelper[1626:115962] method Name :test3
2017-07-17 13:53:48.365 CCNetworkHelper[1626:115962] method Name :setTest3:
2017-07-17 13:53:48.365 CCNetworkHelper[1626:115962] method Name :.cxx_destruct

IvarName 出现了_test5;
经过这两次测试 我认为的可能:
当使用 @property (nonatomic, copy) NSString *test1;时,系统会为我们做两件事 1. 将test1 放入Property中, 2 实现语句 @synthesize test1 = _test1.
而@synthesize 会帮我们做三件事:
1. 声明Ivar _test1并放入 IvarList中
2. 生产set 方法
3. 生成get方法.
我以前一直认为这三件事是 @property做的, 从上面的实验看来这三件事也许是 @synthesize做的.

以上观点都是我测试得出的, 如果有不对的请指正
qq: 2711056454

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值