从GetSet看iOS内存机制 - 1
2015-08-21 10:46
531 查看
在ARC下理解@property和@synthesize机制:
情况一:成员变量 @property @synthesize 同一个名字
结论:成员变量和@property同名且指定@synthesize时候,p-> variable和p.variable效果一样,指的是同一个变量。那为什么会指的是同一个变量呢,因为@synthesize birthday; 编译器会自动监测成员变量有没有同名的,如果有,则做操作:@synthesize birthday = birthday;(后者为成员变量的birthday)。这样属性和成员变量就为同一个变量。那么,假设成员变量没有birthday,只有@property和@synthesize有birthday会怎么样,请看情况五。
情况二:在情况一的基础下将@synthesize去掉
这时候报了一个警告:
大意就是被自动生成的birthday变量将使用自动生成的实例变量_birthday,不存在实例变量birthday。
这时候的输出是:
很明显没有了@synthesize后,@property的birthday和成员变量的birthday完全不是一个变量,这个时候在Person类增加一个输出方法:
在看看结果如下:
很显然说明结果:如果不使用@synthesize,编译器默认自动生成属性birthday为:_birthday即加下划线,其实很多好处,最大好处的防止方法同名(getset中)。
情况三:成员变量使用_position下划线,@property声明没有下划线变量position,@synthesize声明没有下划线变量position
结论:进一步验证了上面的结论@synthesize position; 相当于:@synthesize position = position;而不会自动生成下划线变量。
情况四:成员变量_degress,@property degress,@synthesize degress = _degress
结论:通过@synthesize degress = _degress;相当于将属性degress指定别名_degress,这时候成员变量和属性为同一个变量,而且不能直接获取degress,进一步说明上面的结论。
情况五:成员变量中没有,@property中声明education,@synthesize声明education
结论:如果成员变量没有education,只分别@property education和@synthesize education的话,不生成_education,其实和_position一样情况。只是相当于@synthesize education = education罢了,导致可以直接取。
情况六:成员变量和@synthesize中没有,只在@property中声明weight
情况一:成员变量 @property @synthesize 同一个名字
@interface Person : NSObject { @public NSString* birthday; } @property NSString* birthday; @end
#import "Person.h" @implementation Person @synthesize birthday; @end
#import <UIKit/UIKit.h> #import "AppDelegate.h" #import "Person.h" int main(int argc, char * argv[]) { @autoreleasepool { Person* p = [[Person alloc] init]; p-> birthday = @"1987-08-20";<span style="white-space:pre"> </span>//赋值成员变量 p.birthday = @"1986-08-08";<span style="white-space:pre"> </span>//赋值点取的birthday<span style="white-space:pre"> </span> NSLog(@"p-> birthday :%@ --- %p", p->birthday, p->birthday); //分别输出成员变量和点取的值和地址 NSLog(@"p.birthday :%@ --- %p", p.birthday, p.birthday); return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } }
结论:成员变量和@property同名且指定@synthesize时候,p-> variable和p.variable效果一样,指的是同一个变量。那为什么会指的是同一个变量呢,因为@synthesize birthday; 编译器会自动监测成员变量有没有同名的,如果有,则做操作:@synthesize birthday = birthday;(后者为成员变量的birthday)。这样属性和成员变量就为同一个变量。那么,假设成员变量没有birthday,只有@property和@synthesize有birthday会怎么样,请看情况五。
情况二:在情况一的基础下将@synthesize去掉
这时候报了一个警告:
大意就是被自动生成的birthday变量将使用自动生成的实例变量_birthday,不存在实例变量birthday。
这时候的输出是:
很明显没有了@synthesize后,@property的birthday和成员变量的birthday完全不是一个变量,这个时候在Person类增加一个输出方法:
- (void)printInfo { NSLog(@"_birthdat = %@", _birthday); }
在看看结果如下:
很显然说明结果:如果不使用@synthesize,编译器默认自动生成属性birthday为:_birthday即加下划线,其实很多好处,最大好处的防止方法同名(getset中)。
情况三:成员变量使用_position下划线,@property声明没有下划线变量position,@synthesize声明没有下划线变量position
@interface Person : NSObject { @public NSString* _position; } @property NSString* position; @end
#import "Person.h" @implementation Person @synthesize position; - (void)printInfo { NSLog(@"position = %@", _positon); NSLog(@"position = %@", position); } @end
int main(int argc, char * argv[]) { @autoreleasepool { Person* p = [[Person alloc] init]; p-> _positon = @"developer"; p.position = @"architect"; NSLog(@"p->_position :%@ --- %p", p-> _positon, p-> _positon); NSLog(@"p.position :%@ --- %p", p.position, p.position); [p printInfo]; return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } }
结论:进一步验证了上面的结论@synthesize position; 相当于:@synthesize position = position;而不会自动生成下划线变量。
情况四:成员变量_degress,@property degress,@synthesize degress = _degress
@interface Person : NSObject { @public NSString* _degress; } @property NSString* degress; @end
#import "Person.h" @implementation Person @synthesize degress = _degress; - (void)printInfo { NSLog(@"_degress = %@", _degress); NSLog(@"degress = %@", degress); ----- 报错,不能省 //经修改后 <p class="p1"><span class="s1"> </span><span class="s2">NSLog</span><span class="s1">(</span><span class="s3">@"self.degress = %@"</span><span class="s1">, </span><span class="s4">self</span><span class="s1">.</span><span class="s2">degress</span><span class="s1">);</span></p>} @end
int main(int argc, char * argv[]) { @autoreleasepool { Person* p = [[Person alloc] init]; p.degress = @"undergraduate"; NSLog(@"p->_degress :%@ --- %p", p->_degress, p->_degress); NSLog(@"p.degress :%@ --- %p", p.degress, p.degress); p->_degress = @"graduate"; NSLog(@"p->_degress :%@ --- %p", p->_degress, p->_degress); NSLog(@"p.degress :%@ --- %p", p.degress, p.degress); NSLog(@"----------------------"); [p printInfo]; return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } }
结论:通过@synthesize degress = _degress;相当于将属性degress指定别名_degress,这时候成员变量和属性为同一个变量,而且不能直接获取degress,进一步说明上面的结论。
情况五:成员变量中没有,@property中声明education,@synthesize声明education
#import <Foundation/Foundation.h> @interface Person : NSObject @property NSString* education; @end<span style="color:#cc33cc;"> </span>
#import "Person.h" @implementation Person @synthesize education; - (void)printInfo { NSLog(@"education = %@", self.education); NSLog(@"education = %@", education); } @end
#import <UIKit/UIKit.h> #import "AppDelegate.h" #import "Person.h" int main(int argc, char * argv[]) { @autoreleasepool { Person* p = [[Person alloc] init]; p.education = @"scnu"; [p printInfo]; return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } }
结论:如果成员变量没有education,只分别@property education和@synthesize education的话,不生成_education,其实和_position一样情况。只是相当于@synthesize education = education罢了,导致可以直接取。
情况六:成员变量和@synthesize中没有,只在@property中声明weight
@interface Person : NSObject @property float weight; - (void)printInfo; @end
#import "Person.h" @implementation Person - (void)printInfo { NSLog(@"_weight = %.2f", _weight); NSLog(@"self.weight = %.2f", self.weight); } @end
#import <UIKit/UIKit.h> #import "AppDelegate.h" #import "Person.h" int main(int argc, char * argv[]) { @autoreleasepool { Person* p = [[Person alloc] init]; p.weight = 128.0; [p printInfo]; return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } }
相关文章推荐
- 判断ios中是否安装了某些软件
- IOS开发之图片浏览
- iOS多线程编程:线程同步总结
- iOS 无限后台运行
- IOS_简单创建tableView并使用自定义的单元格
- iOS开发常用的第三方
- iOS 设计模式
- IOS-笔记10(View生命周期)
- iOS开发 -- 音频的播放
- 存储一些iOS常用的资料
- iOS开发~CocoaPods使用详细说明
- ios 数组高级使用
- 阐明iOS证书和provision文件
- iOS ARC也会有内存泄露
- ios线程-GCD
- iOS 浅谈对MVC、传值、和沙盒机制的理解
- ios类别(category)不能添加成员变量但是可以添加属性的问题
- iOS学习——CoreGraphics简单绘图
- iOS 浅谈MVC设计模式及Controllers之间的传值方式
- iOS发展- backBarButtonItem 颜色/文字修改