Automatic Reference Counting (ARC) 是一个编译期的技术,利用此技术可以简化Objective-C编程在内存管理方面的工作量。
这里我把此技术翻译为自动内存计数器管理技术,下图是使用和不使用此技术的Objective-C代码的区别。
ARC技术是随着XCode4.2一起发布的,在缺省工程模板中,你可以指定你的工程是否支持ARC技术,如果你不指定工程支持ARC技术,在代码中你必须使用管理内存的代码来管理内存。
概述
自动计数(ARC)是一个编译期间工作的能够帮你管理内存的技术,通过它,程序人员可以不需要在内存的retain,释放等方面花费精力。
ARC在编译期间为每个Objective-C指针变量添加合适的retain, release, autorelease等函数,保存每个变量的生存周期控制在合理的范围内,以期实现代码上的自动内存管理。
In order for the compiler to generate correct code, ARC imposes some restrictions on the methods you can use, and on how you use toll-free bridging (see “Toll-Free Bridged Types”); ARC also introduces new lifetime qualifiers for object references and declared properties.
你可以使用编译标记-fobjc-arc来让你的工程支持ARC。ARC在Xcode4.2中引入,在Mac OS X v10.6,v10.7 (64位应用),iOS 4,iOS 5中支持,Xcode4.1中不支持这个技术.
如果你现在的工程不支持ARC技术,你可以通过一个自动转换工具来转换你的工程(工具在Edit->Convert menu),这个工具会自动所有工程中手动管理内存的点转换成合适自动方式的(比如移除retain, release等)。这个工具会转换工程中所有的文件。当然你可以转换单个文件。
ARC提供自动内存管理的功能
ARC使得你不需要再思考何时使用retain,release,autorelease这样的函数来管理内存,它提供了自动评估内存生存期的功能,并且在编译期间自动加入合适的管理内存的方法。编译器也会自动生成dealloc函数。一般情况下,通过ARC技术,你可以不顾传统方式的内存管理方式,但是深入了解传统的内存管理是十分有必要的。
下面是一个person类的一个声明和实现,它使用了ARC技术。
@interface Person : NSObject |
@property (nonatomic, strong) NSString *firstName; |
@property (nonatomic, strong) NSString *lastName; |
@property (nonatomic, strong) NSNumber *yearOfBirth; |
@property (nonatomic, strong) Person *spouse; |
@end |
@implementation Person |
@synthesize firstName, lastName, yearOfBirth, spouse; |
@end |
(有关strong的帮助,请参考 “ARC Introduces New Lifetime Qualifiers.”)
使用ARC,你可以象下面的方式实现contrived函数:
- (void)contrived { |
Person *aPerson = [[Person alloc] init]; |
[aPerson setFirstName:@"William"]; |
[aPerson setLastName:@"Dudney"]; |
[aPerson:setYearOfBirth:[[NSNumber alloc] initWithInteger:2011]]; |
NSLog(@"aPerson: %@", aPerson); |
} |
ARC管理内存,所以这里你不用担心aPerson和NSNumber的临时变量会造成内存泄漏。
你还可以象下面的方式来实现Person类中的takeLastNameFrom:方法,
- (void)takeLastNameFrom:(Person *)person { |
NSString *oldLastname = [self lastName]; |
[self setLastName:[person lastName]]; |
NSLog(@"Lastname changed from %@ to %@", oldLastname, [self lastName]); |
} |
ARC可以保证在NSLog调用的时候,oldLastname还存在于内存中。
ARC中的新规则
为了ARC能顺利工作,特增加如下规则,这些规则可能是为了更健壮的内存管理,也有可能为了更好的使用体验,也有可能是简化代码的编写,不论如何,请不要违反下面的规则,如果违反,将会得到一个编译期错误。
-
下面的这些函数:
dealloc,
retain
,release
,retainCount
,autorelease。禁止任何形式调用和实现(dealloc可能会被实现),包括使用
@selector(retain)
,@selector(release)
等的隐含调用。你可能会实现一个和内存管理没有关系的dealloc,譬如只是为了调用
[systemClassInstance setDelegate:nil]
,但是请不要调用[super dealloc]
,因为编译器会自动处理这些事情。 -
你不可以使用
NSAllocateObject
或者
NSDeallocateObject
.使用alloc申请一块内存后,其他的都可以交给运行期的自动管理了。
-
不能在C语言中的结构中使用Objective-c中的类的指针。
请使用类类管理数据。
-
不能使用NSAutoreleasePool
.作为替代,@autoreleasepool被引入,你可以使用这个效率更高的关键词。
-
不能使用memory zones.
NSZone不再需要
—本来这个类已经被现代Objective-c废弃。
ARC在函数和便利变量命名上也有一些新的规定
-
禁止以new开头的属性变量命名。
ARC Introduces New Lifetime Qualifiers
ARC introduces several new lifetime qualifiers for objects, and zeroing weak references. A weak reference does not extend the lifetime of the object it points to. A zeroing weak reference automatically becomes nil
if the object it points to is deallocated.
You should take advantage of these qualifiers to manage the object graphs in your program. In particular, ARC does not guard against strong reference cycles (previously known as retain cycles—see “Practical Memory Management”). Judicious use of weak relationships will help to ensure you don’t create cycles.
属性变量修饰符
weak和strong两个修饰符是新引进的,使用例子如下:
// 下面的作用和: @property(retain) MyClass *myObject;相同 |
@property(strong) MyClass *myObject; |
// 下面的作用和"@property(assign) MyClass *myObject;"相识 |
// 不同的地方在于,如果MyClass的实例析构后,这个属性变量的值变成nil,而不是一个野指针, |
|
@property(weak) MyClass *myObject; |
Variable Qualifiers
You use the following lifetime qualifiers for variables just like you would, say, const
.
__strong |
__weak |
__unsafe_unretained |
__autoreleasing |
__strong
is the default. __weak
specifies a zeroing weak reference to an object. __unsafe_unretained
specifies weak reference to an object that is not zeroing—if the object it references is deallocated, the pointer is left dangling. You use__autoreleasing
to denote arguments that are passed by reference (id *
) and are autoreleased on return.
Take care when using __weak
variables on the stack. Consider the following example:
NSString __weak *string = [[NSString alloc] initWithFormat:@"First Name: %@", [self firstName]]; |
NSLog(@"string: %@", string); |
Although string
is used after the initial assignment, there is no other strong reference to the string object at the time of assignment; it is therefore immediately deallocated. The log statement shows that string
has a null value.
You also need to take care with objects passed by reference. The following code will work:
NSError *error = nil; |
BOOL OK = [myObject performOperationWithError:&error]; |
if (!OK) { |
// Report the error. |
// ... |
However, the error declaration is implicitly:
NSError * __strong e = nil; |
and the method declaration would typically be:
-(BOOL)performOperationWithError:(NSError * __autoreleasing *)error; |
The compiler therefore rewrites the code:
NSError __strong *error = nil; |
NSError __autoreleasing *tmp = error; |
BOOL OK = [myObject performOperationWithError:&tmp]; |
error = tmp; |
if (!OK) { |
// Report the error. |
// ... |
The mismatch between the local variable declaration (__strong
) and the parameter (__autoreleasing
) causes the compiler to create the temporary variable. You can get the original pointer by declaring the parameter id __strong *
when you take the address of a __strong
variable. Alternatively you can declare the variable as __autoreleasing
.
Use Lifetime Qualifiers to Avoid Strong Reference Cycles
You can use lifetime qualifiers to avoid strong reference cycles. For example, typically if you have a graph of objects arranged in a parent-child hierarchy and parents need to refer to their children and vice versa, then you make the parent-to-child relationship strong and the child-to-parent relationship weak. Other situations may be more subtle, particularly when they involve block objects.
In manual reference counting mode, __block id x;
has the effect of not retaining x
. In ARC mode, __block id x;
defaults to retaining x
(just like all other values). To get the manual reference counting mode behavior under ARC, you could use__unsafe_unretained __block id x;
. As the name __unsafe_unretained
implies, however, having a non-retained variable is dangerous (because it can dangle) and is therefore discouraged. Two better options are to either use __weak
(if you don’t need to support iOS 4 or OS X v10.6), or set the __block
value to nil
to break the retain cycle.
The following code fragment illustrates this issue using a pattern that is sometimes used in manual reference counting.
MyViewController *myController = [[MyViewController alloc] init…]; |
// ... |
myController.completionHandler = ^(NSInteger result) { |
[myController dismissViewControllerAnimated:YES completion:nil]; |
}; |
[self presentViewController:myController animated:YES completion:^{ |
[myController release]; |
}]; |
As described, instead, you can use a __block
qualifier and set the myController
variable to nil
in the completion handler:
__block MyViewController *myController = [[MyViewController alloc] init…]; |
// ... |
myController.completionHandler = ^(NSInteger result) { |
[myController dismissViewControllerAnimated:YES completion:nil]; |
myController = nil; |
}; |
Alternatively, you can use a temporary __weak
variable. The following example illustrates a simple implementation:
MyViewController *myController = [[MyViewController alloc] init…]; |
// ... |
__weak MyViewController *weakMyViewController = myController; |
myController.completionHandler = ^(NSInteger result) { |
[weakMyViewController dismissViewControllerAnimated:YES completion:nil]; |
}; |
For non-trivial cycles, however, you should use:
MyViewController *myController = [[MyViewController alloc] init…]; |
// ... |
__weak MyViewController *weakMyController = myController; |
myController.completionHandler = ^(NSInteger result) { |
MyViewController *strongMyController = weakMyController; |
if (strongMyController) { |
// ... |
[strongMyController dismissViewControllerAnimated:YES completion:nil]; |
// ... |
} |
else { |
// Probably nothing... |
} |
}; |
In some cases you can use __unsafe_unretained
if the class isn’t __weak
compatible. This can, however, become impractical for nontrivial cycles because it can be hard or impossible to validate that the __unsafe_unretained
pointer is still valid and still points to the same object in question.
自动释放池
使用ARC,你不能使用NSAutoReleasePool类来管理自动释放池了,作为替代,ARC使用一个新的语法结构:
@autoreleasepool { |
// Code, such as a loop that creates a large number of temporary objects. |
} |
编译器根据工程是否使用ARC,来决定这个语法结构最终呈现方式,这个语法结构使用了一种比NSAutoReleasePool
更高效的方式。
Outlets
The patterns for declaring outlets in iOS and OS X change with ARC and become consistent across both platforms. The pattern you should typically adopt is: outlets should be weak
, except for those from File’s Owner to top-level objects in a nib file (or a storyboard scene) which should be strong
.
Outlets that you create should will therefore generally be weak
by default:
-
Outlets that you create to, for example, subviews of a view controller’s view or a window controller’s window, are arbitrary references between objects that do not imply ownership.
-
The
strong
outlets are frequently specified by framework classes (for example,UIViewController
’sview
outlet, orNSWindowController
’swindow
outlet).
For example:
@interface MyFilesOwnerClass : SuperClass |
@property (weak) IBOutlet MyView *viewContainerSubview; |
@property (strong) IBOutlet MyOtherClass *topLevelObject; |
@end |
In cases where you cannot create a weak reference to an instance of a particular class (such as NSTextView
), you should use assign
rather than weak
:
@property (assign) IBOutlet NSTextView *textView; |
This pattern extends to references from a container view to its subviews where you have to consider the internal consistency of your object graph. For example, in the case of a table view cell, outlets to specific subviews should again typically beweak
. If a table view contains an image view and a text view, then these remain valid so long as they are subviews of the table view cell itself.
Outlets should be changed to strong
when the outlet should be considered to own the referenced object:
-
As indicated previously, this often the case with File’s Owner: top level objects in a nib file are frequently considered to be owned by the File’s Owner.
-
You may in some situations need an object from a nib file to exist outside of its original container. For example, you might have an outlet for a view that can be temporarily removed from its initial view hierarchy and must therefore be maintained independently.
其他的新功能
使用ARC技术,可以使得在栈上分配的指针隐式的初始化为nil,比如
- (void)myMethod { |
NSString *name; |
NSLog(@"name: %@", name); |
} |
上面的代码会Log出来一个null,不会象不使用ARC技术的时候使得程序崩溃。
相关推荐
基于苍鹰优化算法的NGO支持向量机SVM参数c和g优化拟合预测建模(Matlab实现),苍鹰优化算法NGO优化支持向量机SVM的c和g参数做多输入单输出的拟合预测建模。 程序内注释详细直接替数据就可以使用。 程序语言为matlab。 程序直接运行可以出拟合预测图,迭代优化图,线性拟合预测图,多个预测评价指标。 PS:以下效果图为测试数据的效果图,主要目的是为了显示程序运行可以出的结果图,具体预测效果以个人的具体数据为准。 2.由于每个人的数据都是独一无二的,因此无法做到可以任何人的数据直接替就可以得到自己满意的效果。 ,核心关键词:苍鹰优化算法; NGO优化; 支持向量机SVM; c和g参数; 多输入单输出拟合预测建模; Matlab程序; 拟合预测图; 迭代优化图; 线性拟合预测图; 预测评价指标。,MATLAB实现:基于苍鹰优化算法与NGO优化SVM的c和g参数多输入单输出预测建模工具
麻雀优化算法SSA优化广义神经网络GRNN的多特征输入单变量输出拟合预测模型(Matlab实现),麻雀优化算法SSA优化广义神经网络GRNN做多特征输入,单个因变量输出的拟合预测模型。 程序内注释详细直接替数据就可以用。 程序语言为matlab。 ,关键词:麻雀优化算法(SSA);优化;广义神经网络(GRNN);多特征输入;单个因变量输出;拟合预测模型;Matlab程序语言;程序内注释。,SSA优化GRNN的多特征输入-单因变量输出拟合预测模型(基于Matlab程序)
2025最新辐射安全与防护培训考试题库及答案.docx
高效数字电源方案:图腾柱无桥pfc技术,两相交错设计,5G一体化电源批量出货,宽电压输入与高效输出,功率覆盖至kW级别,高效数字电源方案,图腾柱无桥pfc,两相交错,5g一体化电电源上已批量出,输入175-265V,输出42-58V;输出效率97%,2kW 3kW都有 ,高效数字电源方案; 图腾柱无桥pfc; 两相交错; 5g一体化电电源; 批量出货; 宽输入电压范围; 高输出效率; 2kW和3kW功率。,"高效图腾柱无桥PFC电源方案,两相交错5G电平已大批量生产,宽输入范围输出高效率"
项目已获导师指导并通过的高分毕业设计项目,可作为课程设计和期末大作业,下载即用无需修改,项目完整确保可以运行。 包含:项目源码、数据库脚本、软件工具等,该项目可以作为毕设、课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 项目都经过严格调试,确保可以运行!可以放心下载 技术组成 语言:java 开发环境:idea 数据库:MySql8.0 部署环境:Tomcat(建议用 7.x 或者 8.x 版本),maven 数据库工具:navicat
2025糖医帮认证考试题库(附含答案).docx
MATLAB下的模型预测控制在楼宇负荷需求响应中的研究与应用:结合热力学与舒适度考量,MATLAB代码:基于模型预测控制的楼宇负荷需求响应研究 关键词:楼宇负荷 空调 模型预测控制 需求响应 参考文档:《Model Predictive Control of Thermal Storage for Demand Response》完全复现 仿真平台:MATLAB+CVX平台 主要内容:代码主要做的是一个建筑楼宇的需求响应问题,首先利用楼宇的储热特性,结合热力学方程构建了其储热模型,其次,考虑在动态能量电价的引导下,对楼宇负荷进行需求侧管理,从而能够对其负荷曲线进行改善,在需求响应的过程中也考虑了用户的舒适度,相对来讲比较全面,模型的求解采用的是较为创新的模型预测控制算法,更加创新,而且求解的效果更好,店主已经对代码进行了深入的加工和处理,出图效果非常好,代码质量非常高 ,关键词:楼宇负荷; 空调; 模型预测控制; 需求响应; 储热模型; 动态能量电价; 舒适度; MATLAB代码; CVX平台; 深入处理。,基于MATLAB的模型预测控制研究:楼宇负荷需求响应管理与优化
樽海鞘优化算法SSA:Matlab实现与基准测试函数详解,樽海鞘优化算法 SSA (matlab代码,包含23个常用的基准测试函数)可直接运行效果如图所示 ,核心关键词:樽海鞘优化算法(SSA); Matlab代码; 基准测试函数; 可直接运行; 效果图。,樽海鞘优化算法SSA的Matlab实现:23个基准测试函数直接运行效果图
基于主从博弈的电热综合能源系统动态定价策略与能量管理优化模型——粒子群算法与CPLEX求解器的应用,MATLAB代码:基于主从博弈的电热综合能源系统动态定价与能量管理 关键词:主从博弈 电热综合能源 动态定价 能量管理 参考文档:店主自编文档,完全复现 仿真平台:MATLAB 平台 优势:代码具有一定的深度和创新性,注释清晰,非烂大街的代码,非常精品 主要内容:代码主要做的是电热综合能源系统的动态定价问题,采用是主从博弈方法,上领导者问题上,以综合能源系统整体的收益作为目标函数,考虑电价以及热价等相关约束,在下层跟随者模型上,以用户用能满意度最高为目标函数,构建了领导者-跟随者Stackelberg博弈模型,同时还考虑了系统的功率平衡条件以及热能平衡条件等约束,模型的上层求解采用粒子群算法,下层求解采用CPLEX求解器,考虑该代码具有一定的创新性,适合新手学习以及在此基础上进行拓展,代码质量非常高 ,基于主从博弈; 电热综合能源系统; 动态定价; 能量管理; Stackelberg博弈模型; 粒子群算法; CPLEX求解器。,基于主从博弈的电热综合能源系统动态定价与能量管理MA
Python游戏编程源码-Python编码生成系统.zip
哈里斯鹰优化算法HHO Matlab代码展示与性能评测报告(涵盖多项基准测试),哈里斯鹰优化算法 HHO (matlab代码,包含23个常用的基准测试函数)可直接运行效果如图所示 ,核心关键词:哈里斯鹰优化算法(HHO); MATLAB代码; 基准测试函数; 可直接运行; 效果如图所示; 23个常用函数。,"HHO算法Matlab实现:23个基准测试函数优化效果图解"
2025中药鉴定技术考试题库及答案.docx
基于主从博弈的电热综合能源系统动态定价与能量管理策略优化——粒子群算法与CPLEX求解器的应用,MATLAB代码:基于主从博弈的电热综合能源系统动态定价与能量管理 超值 关键词:主从博弈 电热综合能源 动态定价 能量管理 粒子群算法 cplex求解 参考文档:店主自编文档,完全复现 仿真平台:MATLAB 平台 主要内容:代码主要做的是电热综合能源系统的动态定价问题,采用是主从博弈方法,上领导者问题上,以综合能源系统整体的收益作为目标函数,考虑电价以及热价等相关约束,在下层跟随者模型上,以用户用能满意度最高为目标函数,构建了领导者-跟随者Stackelberg博弈模型,同时还考虑了系统的功率平衡条件以及热能平衡条件等约束,模型的上层求解采用粒子群算法,下层求解采用CPLEX求解器,考虑该代码具有一定的创新性,适合新手学习以及在此基础上进行拓展,代码跑出质量甚佳 ,主从博弈; 电热综合能源; 动态定价; 能量管理; 粒子群算法; cplex求解; 创新; 新手学习,基于主从博弈的电热综合能源系统动态定价与能量管理策略:粒子群算法与Cplex求解的MATLAB实现
基于碳捕集电厂低碳特性与综合能源系统的多时间尺度电热调度模型:灵活运行与需求响应协同优化。,计及碳捕集电厂低碳特性 需求响应 综合能源系统 多时间尺度调度模型 MATLAB代码: 关键词:碳捕集电厂 综合灵活运行方式 需求响应 日前调度 实时调度 参考文档:《计及碳捕集电厂低碳特性的含风电电力系统源-荷多时间尺度调度方法》非完全复现,只做了日前日内部分,并在上述基础上改进升级为电热综合电源系统 仿真平台:MATLAB yalmip+cplex 主要内容:代码主要做的是一个电厂 微网多时间尺度电热综合能源系统低碳经济调度模型,源侧在碳捕集电厂中装设烟气旁路系统与溶液存储器,形成碳捕集电厂综合灵活运行方式进而与风电协调配合;荷侧调用不同响应速度的价格型、激励型需求响应资源克服多时间尺度下碳捕集电厂综合灵活运行方式的局限,通过源荷资源协调优化,从而提高系统的低碳性能。 其次,构建源荷协调的日前-日内两阶段低碳经济调度模型,优化系统的负荷及分配计划。 ,关键词:碳捕集电厂;综合灵活运行方式;需求响应;日前调度;实时调度;电热综合能源系统;多时间尺度调度模型;源荷协调
项目已获导师指导并通过的高分毕业设计项目,可作为课程设计和期末大作业,下载即用无需修改,项目完整确保可以运行。 包含:项目源码、数据库脚本、软件工具等,该项目可以作为毕设、课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 项目都经过严格调试,确保可以运行!可以放心下载 技术组成 语言:java 开发环境:idea 数据库:MySql8.0 部署环境:Tomcat(建议用 7.x 或者 8.x 版本),maven 数据库工具:navicat
Python游戏编程源码-pygame编植物大战僵尸2
风速对空调实验室气流分布均匀性的影响分析.pdf
粒子滤波算法在目标跟踪中的实践与源码解析集合:多套系统源码包括基于meanshift的应用、MATLAB实现及与卡尔曼滤波比较,粒子滤波(器)滤波(器)及应用源码集合目标跟踪提取图像特征 以下多套系统源码 1、基于meanshift和粒子滤波的目标跟踪代码 2、MATLAB编写的粒子滤波器的源代码 3、粒子滤波算法实例 4、粒子滤波mcmc介绍 5、粒子滤波算法 matlab(粒子滤波用于剩余寿命预测的实例代码 MATLAB语言编写 附有详细代码说明) 6、粒子滤波matlab代码(能够运行。 Pf粒子滤波实现的目标跟踪程序,可实现针对非高斯噪声情况下的跟踪) 7、粒子滤波代码(三个粒子滤波的演示程序,一个滤波,一个目标跟踪,一个机器人定位) 8、发个Matlab实现粒子滤波算法的程序 9、粒子滤波的简介和5中matlab程序仿真 10、粒子滤波代码与卡尔曼做比较(这是用于目标跟踪的粒子滤波代码, 用matlab编写的,很有借鉴性,一维情况下, 非高斯非线性,其中将扩展卡尔曼滤波与粒子滤波进行比较,更好的说明了粒子滤波的优越性) 11、EKF,UKF和PF粒子滤波的性能(对比分析EKF
1、资源内容地址:https://blog.csdn.net/2301_79696294/article/details/144633829 2、数据特点:今年全新,手工精心整理,放心引用,数据来自权威,且标注《数据来源》,相对于其他人的控制变量数据准确很多,适合写论文做实证用 ,不会出现数据造假问题 3、适用对象:大学生,本科生,研究生小白可用,容易上手!!! 4、课程引用: 经济学,地理学,城市规划与城市研究,公共政策与管理,社会学,商业与管理