IOS5(自动引用计数器) 的属性介绍
来源:互联网 发布:drgs分组器软件 编辑:程序博客网 时间:2024/05/29 19:11
目前自引进了iOS5,iPhone,iPad,iPodTouch的编程改变了很多。整个runtime和objective-c的编码方式发生了很大的改变。 在下面的文章中,我们会谈谈在objective-c runtime ARC下,怎样使用对象和管理它们!
从手工引用计数到自动引用计数(ARC)
问题: 学习Automatic Reference Counting(自动引用计数器),苹果的新的编译器解决了令人头痛的问题:在Objective-C中,当使用对象的时候,处理对象,以及管理内存。
解决: 由最新的LLVM编译器引进的新的属性存储技术:strong, weak,和unsafe_unretained
描述“在最新的LLVM编译器中,是使用了Automatic Reference Counting(ARC),我们需要处理strong,weak,或者unsafe和unretained存储技术。在ARC模式之下的对象,是由 :
如果使用@"String 1"初始化string1,并将string1的属性值分配给string2,那么有着存储属性(storage attribute)的string2属性将会保存string1的值,即使在string1销毁后,string2仍然保存@"String 1"值。
在声明属性的时候strong, weak, unsafe_unretained会经常被用到。即使在声明局部变量的时候你也可以使用这些存储说明符,但是你需要对说明符做一点修改。strong等效的嵌入说明符为__strong,weak等效的嵌入说明符为__weak,unsafe_unretained等效的嵌入说明符为__unsafe_unretained。(记住这些关键字是以2个下划线开头),如下:
当object被销毁了,这时候要解决很多的问题,但是,ARC中的“归零弱引用有用,可以解决很多问题。weak引用:当指针指向的对象被销毁了,那么weak引用的对象(a zeroing reference's object)会被设置为nil。所有指向被回收对象的weak引用(the weak referencing pointers),都会被设置为nil。
unsafe_unretained存储说明符是真正安全的,就像它的名字寓意。它安全的原因是:当unsafe_unretained变量指向的对象(object)被回收销毁了,这个变量会被设置为nil,并且将会指向内存中的a dangling location。访问这个地址可能引起程序的崩溃。为了避免这种情况,你应该使用“归零弱引用存储说明符 - zeroing weak referencing storage specifier”,weak或者内嵌(inline equivalent)说明符。
现在运行程序,等到1-2秒钟后,点击Home按钮。你将会注意到接下来的结果将会被打印到控制台中:
这很容易证明ARC的“归零弱引用 - zeroing weak referencing”,实现的很完美。现在检查unsafe_unretained存储说明符是多么的危险,代码例子:
AppDelegate的实现部分,就像我们之前实现的一样,在程序进入后台的时候打印string2的值,并重复打开和最小化程序的操作,程序和crash!这就意味我们的应用程序被送到后台的时候,试图打印内存中无效对象(string2指向的对象)的内容人,然而,string2属性不安全并且 unretained(没有retain),所以string2不知道它指向的对象(in string1),当string1被设置为nil,已经被回收销毁。
除上述的3个存储说明符,我们还可以使用_说明符。如我们想向方法传递对象的引用的时候,存储说明符是最方便的。如,方法需要向调用方法(the caller method),传递一个NSError的error对象,方法将会向调用方法(the caller method)传递一个未初始化并且未分配的NSError实例对象。这就意味着调用者不需要分配这个error对象,所以,我们的方法就应该这样做。为了实现这个,error参数需要是自动释放对象,在合适的时间点的时候,通过runtime释放。
从手工引用计数到自动引用计数(ARC)
问题: 学习Automatic Reference Counting(自动引用计数器),苹果的新的编译器解决了令人头痛的问题:在Objective-C中,当使用对象的时候,处理对象,以及管理内存。
解决: 由最新的LLVM编译器引进的新的属性存储技术:strong, weak,和unsafe_unretained
描述“在最新的LLVM编译器中,是使用了Automatic Reference Counting(ARC),我们需要处理strong,weak,或者unsafe和unretained存储技术。在ARC模式之下的对象,是由 :
strong:这种类型的对象在run-time的时候自动增加引用计数,并在它范围结束之前有效,之后就会被自动释放,熟悉Objective-C传统的内存管理办法的话,这个关键字和retain关键字很相似。
weak:这是 “归零弱引用 ”。如果变量使用这个关键字定义,当对象(变量指向的内存)被销毁了,这个变量会被设置为nil。例如:你有一个strong的string属性和一个weak的string属性,并将weak属性的值设置为strongoing属性的值,当strong属性被销毁了,那么weak属性就会被设置为nil。unsafe_unretained:简单的将一个变量指向另一个变量。设置对象的新数值,不会增加它的引用计数,它只是简单的为变量分配了一个对象而。
默认,所有的局部变量是strong变量。反之,属性必须明确指定它们的存储属性。你需要确定将你的属性指定为存储属性,看看下面的例子吧:
#import <UIKit/UIKit.h>@interface Moving_from_Manual_Reference_Counting_to_ARCAppDelegate : UIResponder <UIApplicationDelegate>@property (strong, nonatomic) UIWindow *window;@property (nonatomic, strong) NSString *string1;@property (nonatomic, strong) NSString *string2;@end
如果使用@"String 1"初始化string1,并将string1的属性值分配给string2,那么有着存储属性(storage attribute)的string2属性将会保存string1的值,即使在string1销毁后,string2仍然保存@"String 1"值。
#import "Moving_from_Manual_Reference_Counting_to_ARCAppDelegate.h"@implementation Moving_from_Manual_Reference_Counting_to_ARCAppDelegate@synthesize window = _window;@synthesize string1;@synthesize string2;- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{self.string1 = @"String 1";self.string2 = self.string1; self.string1 = nil;NSLog(@"String 2 = %@", self.string2);self.window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];self.window.backgroundColor = [UIColor whiteColor];[self.window makeKeyAndVisible];return YES;}输出为:String 2 = String 1
在声明属性的时候strong, weak, unsafe_unretained会经常被用到。即使在声明局部变量的时候你也可以使用这些存储说明符,但是你需要对说明符做一点修改。strong等效的嵌入说明符为__strong,weak等效的嵌入说明符为__weak,unsafe_unretained等效的嵌入说明符为__unsafe_unretained。(记住这些关键字是以2个下划线开头),如下:
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{/* All local variables are by default strong so just emphasis that.We really don't have to mention __strong for the first variable but to make it clear,we will set it. No harm in doing so. */__strong NSString *yourString = @"Your String";__weak NSString *myString = yourString;yourString = nil;__unsafe_unretained NSString *theirString = myString;/* All pointers will be nil at this time */self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];self.window.backgroundColor = [UIColor whiteColor];[self.window makeKeyAndVisible];return YES;}
当object被销毁了,这时候要解决很多的问题,但是,ARC中的“归零弱引用有用,可以解决很多问题。weak引用:当指针指向的对象被销毁了,那么weak引用的对象(a zeroing reference's object)会被设置为nil。所有指向被回收对象的weak引用(the weak referencing pointers),都会被设置为nil。
unsafe_unretained存储说明符是真正安全的,就像它的名字寓意。它安全的原因是:当unsafe_unretained变量指向的对象(object)被回收销毁了,这个变量会被设置为nil,并且将会指向内存中的a dangling location。访问这个地址可能引起程序的崩溃。为了避免这种情况,你应该使用“归零弱引用存储说明符 - zeroing weak referencing storage specifier”,weak或者内嵌(inline equivalent)说明符。
#import <UIKit/UIKit.h>@interface Moving_from_Manual_Reference_Counting_to_ARCAppDelegate : UIResponder <UIApplicationDelegate>@property (strong, nonatomic) UIWindow *window;@property (nonatomic, strong) NSString *string1;@property (nonatomic, weak) NSString *string2;@end程序第一次运行的时候,将会初始化strong类的string1属性,然后将string1分配给string2.然后我们将string1的值设为nil。然后等待,这绝对是至关重要的。runloop除去所有无效的对象。为了实现这个目标,我们在应用程序将要进入后台的时候,我们将打印string2的值。(这是在用户将另一个应用程序移到前台时,你的应用程序进入后台)。一旦程序在后台运行,我们知道runloop已经除去了内存中所有无效对象,并且我们得到的结果将是正确的:
/* 3 */- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{self.string1 = [[NSString alloc] initWithUTF8String:"String 1"];self.string2 = self.string1; self.string1 = nil;/* All pointers will be nil at this time */self.window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];self.window.backgroundColor = [UIColor whiteColor];[self.window makeKeyAndVisible];return YES;}- (void)applicationDidEnterBackground:(UIApplication *)application{NSLog(@"String 2 = %@", self.string2);
现在运行程序,等到1-2秒钟后,点击Home按钮。你将会注意到接下来的结果将会被打印到控制台中:
String 2 = (null)
这很容易证明ARC的“归零弱引用 - zeroing weak referencing”,实现的很完美。现在检查unsafe_unretained存储说明符是多么的危险,代码例子:
#import <UIKit/UIKit.h>@interface Moving_from_Manual_Reference_Counting_to_ARCAppDelegate : UIResponder <UIApplicationDelegate>@property (strong, nonatomic) UIWindow *window;@property (nonatomic, strong) NSString *string1;@property (nonatomic, unsafe_unretained) NSString *string2;@end
AppDelegate的实现部分,就像我们之前实现的一样,在程序进入后台的时候打印string2的值,并重复打开和最小化程序的操作,程序和crash!这就意味我们的应用程序被送到后台的时候,试图打印内存中无效对象(string2指向的对象)的内容人,然而,string2属性不安全并且 unretained(没有retain),所以string2不知道它指向的对象(in string1),当string1被设置为nil,已经被回收销毁。
除上述的3个存储说明符,我们还可以使用_说明符。如我们想向方法传递对象的引用的时候,存储说明符是最方便的。如,方法需要向调用方法(the caller method),传递一个NSError的error对象,方法将会向调用方法(the caller method)传递一个未初始化并且未分配的NSError实例对象。这就意味着调用者不需要分配这个error对象,所以,我们的方法就应该这样做。为了实现这个,error参数需要是自动释放对象,在合适的时间点的时候,通过runtime释放。
- (void) generateErrorInVariable:(__autoreleasing NSError **)paramError{ //the caller method,声明参数的类型是自动释放的类型NSArray *objects = [[NSArray alloc] initWithObjects:@"A simple error", nil];NSArray *keys = [[NSArray alloc] initWithObjects:NSLocalizedDescriptionKey, nil];NSDictionary *errorDictionary = [[NSDictionary alloc] initWithObjects:objects forKeys:keys];*paramError = [[NSError alloc] initWithDomain:@"MyApp" code:1 userInfo:errorDictionary];}- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{NSError *error = nil;[self generateErrorInVariable:&error];NSLog(@"Error = %@", error);self.window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible];return YES;}
- IOS5(自动引用计数器) 的属性介绍
- Objective-C - 自动引用计数器
- Python的引用计数器
- iOS ARC 自动引用计数器详解
- 第十三篇:ARC自动引用计数器原理
- 引用计数器的基本操作
- ios5新特性:自动引用计数(ARC)详解
- 引用计数器
- 引用计数器
- 7.引用计数器的基本操作
- 对象的创建与引用计数器实现
- OC_语法入门_day5_内存管理_计数器/set方法/property的参数/循环引用/自动释放池
- IOS5之后添加的 UIViewController的属性和方法
- UIViewController的parentViewController属性在iOS5下发生了改变
- iOS5的strong,weak,unsafe_unretained ARC自动管理内存
- reference counter 引用计数器
- 初学c++引用计数器
- MRC环境 引用计数器
- Android Init进程分析
- HDU1303:Doubles
- spring 定时任务的具体实现
- 关于table的那些用法(一)
- 相似图片搜索的原理(二)
- IOS5(自动引用计数器) 的属性介绍
- 24点计算
- 概念辨析:dBm, dBi, dBd, dB, dBc
- android meta-data
- usb摄像头方案厂商
- NFC bcm2079x驱动学习
- form表单提交get请求,后台接收乱码的解决方案
- 配置MySQL Workbench
- 树形结构实现并查集