我在线阅读了很多文章,我对ARC感到有点困惑。我将在下面列出我的问题,请帮我回答。
1。)关键字strong
做什么(在@property (nonatomic, strong) …
中)?
2。)我们不再需要release
或autorelease
我们alloc
了,因为我得到一个警告说我不需要。 (我不在我的Mac上,所以我无法复制我收到的警告。)
3.)我在Xcode 4.2中找不到Leaks工具。它去了哪里?或者我们不必再检查泄漏了吗?
4。)使用Xcode 4.2创建项目时,我点击了“启用ARC”,那么我的程序是否可以在iOS 3上运行? (我认为ARC仅支持iOS 4及更高版本。)
答案 0 :(得分:7)
strong
是retain
的ARC模拟(ARC下没有retain
)。这意味着属性值将由定义@property
的类保持,并在重新分配或释放时释放。 (请注意,在ARC下,无需在dealloc中释放或取消属性)。
ARC的重点在于编译器处理retain
/ release
例程,因此不需要手动内存管理方法。
您可以通过运行个人资料(Product -> Profile
菜单)并选择泄漏工具来检查是否有泄漏。可以使用循环引用或CoreFoundation代码引入泄漏(ARC不适用于CoreFoundation)。此外,如果您混合ARC和非ARC代码,后者可能是泄漏的来源。
从iOS 4.0开始,操作系统支持ARC(虽然需要iOS 5 SDK)。 4.0和5.0 ARC支持之间的关键区别是weak
属性说明符的可用性。当引用的__weak
值被释放时,弱属性(strong
变量)将自动无效。 4.0中没有weak
属性,因此应该使用__unsafe_unretained
说明符(它与assign
说明符类似,它不保留值并且可以指向已经释放的值,所以这很危险。)
以下是ARC的一个很好的解释: Everything you need to know about automatic reference counting
答案 1 :(得分:6)
Strong相当于ARC中的retain
。它表示所有权:What does the "strong" keyword do
不,那已经为你完成了。 ARC自动在(编译)代码中插入这些语句。这是它的主要工作。但是,根据Abizern的评论,这仅适用于您的对象和Cocoa对象。如果您正在使用Core Foundation(CF*
)类,那么您必须阅读有关__bridge
系列演员表的内容。 You might start reading here.
它在仪器中。根据iHunter的回答,Cmd + I或Product-> Profile,然后选择Leaks。特别重要的是(2)。
它不起作用。
答案 2 :(得分:2)
嗯,已经有三个答案涵盖了主要内容,所以我将专注于这里的一个细节,这还没有提到:
3.)我在Xcode 4.2中找不到Leaks工具。它去了哪里? 或者我们不能再检查泄漏了吗?
是的,我们仍然需要检查泄漏:
ARC不是垃圾收集,它是自动保留/释放。
因此,它仍然可能 - 事实上,很容易造成泄漏!
考虑以下示例:
@class Puppet;
@protocol PuppetDelegate : <NSObject>
- (void)puppetDidTwistStrings:(Puppet *)puppet;
@end
@interface Puppet : NSObject {
id <PuppetDelegate> delegate_;
}
- (id)initWithPuppetDelegate:(id <PuppetDelegate>)delegate;
- (void)unravelStrings;
@end
@implementation Puppet
- (id)initWithPuppetDelegate:delegate
{
if (!(self = [super init])) return nil;
delegate_ = delegate;
return self;
}
// assume some implementation for unravel strings
@end
@interface MasterOfPuppets : NSObject <PuppetDelegate> {
NSMutableArray *puppets_;
}
- (void)puppetDidTwistStrings:(Puppet *)puppet;
- (void)bringOutAPuppet;
@end
@implementation
- (id)init
{
if (!(self = [super init])) return nil;
puppets_ = [[NSMutableArray alloc] init];
return self;
}
- (void)bringOutAPuppet
{
Puppet *newPuppet = [[Puppet alloc] initWithPuppetDelegate:self];
[puppets_ addObject:newPuppet];
}
- (void)puppetDidTwistStrings:(Puppet *)puppet
{
BOOL isOurPuppet = [puppets_ containsObject:puppet];
if (!isOurPuppet) return;
[puppet unravelStrings];
}
@end
这个例子(不可否认)有点愚蠢,但是这段代码会泄漏,ARC不会帮你解决这个问题,而垃圾收集则会:
在非ARC代码中,实例变量只是一个指定的指针,ARC假定如果你在变量中存放某些东西,你想要依赖它,它将retain
值除非你告诉它不要。
所以你在这里有一个经典的保留周期,ARC不会让你免于那些。
这似乎是一个人为的,牵强附会的例子,但事实并非如此:我在委托关系中已经看到了这一点。
(顺便说一句,解决方案非常简单:将Puppet
的{{1}}实例变量声明为delegate_
,一切正常。