以下のコードでは、GCC_OPTIMIZATION_LEVEL を None に設定して実行すると、実行は期待どおりに機能し、コンソールに次のように出力されます。
My Obj - SomeObj
ただし、GCC_OPTIMIZATION_LEVEL を Xcode ターゲット構成で Fastest, Smallest に設定すると (通常、リリース ビルドで行うように)、コンソールに次のように出力されます。
My obj - (null)
[Foo doSomething] の __weak id myObj 変数に格納すると、オブジェクトが解放されているように見えます。myObj 変数から __weak フラグを削除すると、GCC_OPTIMIZATION_LEVEL が Fastest, Smallest に設定されているときに、コードが期待どおりに実行されます。
この例は、別のプロジェクトで使用した同様のパターンに基づいて作成し、保持サイクルが発生していたため、__weak フラグを追加しました。リテイン サイクルの警告はなくなりましたが、Release 用にビルドしたときに、この例でログに記録している場所に到達するまでに myObj が nil になることがわかりました。
__weak フラグを設定することで、どのような規則に違反していますか?
#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