Objective c 关于GCC优化级别,影响块中弱变量的规则是什么?

Objective c 关于GCC优化级别,影响块中弱变量的规则是什么?,objective-c,automatic-ref-counting,block,Objective C,Automatic Ref Counting,Block,在下面的代码中,当我在GCC_OPTIMIZATION_LEVEL设置为None的情况下运行它时,执行工作与我预期的一样,并将以下内容打印到控制台: My Obj - SomeObj My obj - (null) 但是,当我将GCC_优化_级别设置为Xcode目标配置中最快、最小的级别时(正如发布版本通常所做的那样),我会在控制台上打印以下内容: My Obj - SomeObj My obj - (null) 当我将对象存储到[Foo doSomething]中的uu弱id myOb

在下面的代码中,当我在GCC_OPTIMIZATION_LEVEL设置为None的情况下运行它时,执行工作与我预期的一样,并将以下内容打印到控制台:

My Obj - SomeObj
My obj - (null)
但是,当我将GCC_优化_级别设置为Xcode目标配置中最快、最小的级别时(正如发布版本通常所做的那样),我会在控制台上打印以下内容:

My Obj - SomeObj
My obj - (null)
当我将对象存储到[Foo doSomething]中的uu弱id myObj变量中时,该对象似乎被释放。如果我从myObj变量中删除uu弱标志,那么当GCC_优化_级别设置为最快、最小时,代码将按预期运行

我基于另一个项目中的类似模式构建了这个示例,并添加了_弱标志,因为我遇到了一个保留周期。retain cycle警告消失了,但当我为发布构建时,我发现myObj在到达我在本例中记录它的位置时将为零

我设置弱标志违反了什么规则

#import "FFAppDelegate.h"


///////////////////////////////////////////////////////
@interface SomeObject : NSObject

@end

@implementation SomeObject

- (NSString *)description; {
    return @"SomeObject";
}

@end


///////////////////////////////////////////////////////
@interface Factory : NSObject
@end

@implementation Factory

- (id)generateObj {
    id myObj = nil;
    if (!myObj) {
        SomeObject *anObj = [[SomeObject alloc] init];
        myObj = anObj;
    }
    return myObj;
}


@end


///////////////////////////////////////////////////////
@interface Bar : NSObject

- (id)barObj;

@end

@implementation Bar
{
    Factory *factory;
}

- (id)init {
    self = [super init];
    if (self) {
        factory = [[Factory alloc] init];
    }
    return self;
}
- (id)barObj {
    id anObj = [factory generateObj];
    return anObj;
}

@end


///////////////////////////////////////////////////////
@interface Foo : NSObject

@property (strong) Bar *aBar;

- (void)doSomething;

@end

@implementation Foo

- (id)init {
    self = [super init];
    if (self) {
        _aBar = [[Bar alloc] init];
    }
    return self;
}

- (void)doSomething {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        __weak id myObj = [self.aBar barObj];
        NSLog(@"My Obj - %@", myObj);
    });
}

@end


///////////////////////////////////////////////////////
@implementation FFAppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    Foo *f = [[Foo alloc] init];
    [f doSomething];
}

@end
我设置弱标志违反了什么规则

#import "FFAppDelegate.h"


///////////////////////////////////////////////////////
@interface SomeObject : NSObject

@end

@implementation SomeObject

- (NSString *)description; {
    return @"SomeObject";
}

@end


///////////////////////////////////////////////////////
@interface Factory : NSObject
@end

@implementation Factory

- (id)generateObj {
    id myObj = nil;
    if (!myObj) {
        SomeObject *anObj = [[SomeObject alloc] init];
        myObj = anObj;
    }
    return myObj;
}


@end


///////////////////////////////////////////////////////
@interface Bar : NSObject

- (id)barObj;

@end

@implementation Bar
{
    Factory *factory;
}

- (id)init {
    self = [super init];
    if (self) {
        factory = [[Factory alloc] init];
    }
    return self;
}
- (id)barObj {
    id anObj = [factory generateObj];
    return anObj;
}

@end


///////////////////////////////////////////////////////
@interface Foo : NSObject

@property (strong) Bar *aBar;

- (void)doSomething;

@end

@implementation Foo

- (id)init {
    self = [super init];
    if (self) {
        _aBar = [[Bar alloc] init];
    }
    return self;
}

- (void)doSomething {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        __weak id myObj = [self.aBar barObj];
        NSLog(@"My Obj - %@", myObj);
    });
}

@end


///////////////////////////////////////////////////////
@implementation FFAppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    Foo *f = [[Foo alloc] init];
    [f doSomething];
}

@end
在您的示例中,没有对从
[self.aBar barObj]
返回的实例的强引用。因此,您不能假设在读取
myObj
变量时实例将处于活动状态

在未优化的构建中,返回的实例已添加到自动释放池中,因此在打印
myObj
时仍处于活动状态。您可以通过在
-[SomeObject dealloc]
中设置断点来验证这一点

在优化的构建中,ARC避免了自动释放池,因此返回的实例将立即释放

有关更多信息,请参阅。具体而言:

当从这样的函数或方法返回时,ARC会在return语句的求值点保留该值,然后离开所有局部作用域,然后平衡retain,同时确保该值跨越调用边界。在最坏的情况下,这可能涉及自动释放,但调用者不得假设该值实际上在自动释放池中


当使用
\uu-weak
来避免保留循环时,您必须确保在其他地方有一个强引用来保持对象的活动状态。

也许您应该使用Apple的默认编译器LLVM,而不是GCC


编辑:而且你的“工厂”方法看起来是错误的。例如,在该if中,对象始终为零。浏览一下:

为了防止保留循环,您需要在块外创建一个弱引用。这正是我为解决此问题所做的。谢谢。我正在使用LLVM。LLVM使用GCC_优化_级别标志。