簡體   English   中英

為什么不訪問self的屬性會在self擁有的塊中引發編譯器警告

[英]Why doesn't accessing self's property raise compiler warning in block owned by self

我對內存管理/保留周期有點困惑。 這是一個簡單的類:

@interface Test : NSObject {
    NSObject *objectA;
}
@property (nonatomic, strong) NSObject *objectB;

- (void)methodA;
@end

假設我有一個由Test實例擁有的塊。 在這個塊我做:

    objectA = nil;

我得到一個編譯器減弱說它在這個塊中捕獲自我並且它將導致保留周期。 為什么? 我在這里看不到自己。

如果我這樣做:

self.objectB = nil;

沒有警告! 如果有的話,我應該在這里發出警告。

如果我這樣做:

[self methodA];

我在這里得到一個警告。 所以我不確定幕后發生了什么。 我希望第一個不給我一個警告,最后兩個給我一個警告(因為我保持一個強烈的指針自我),但實際上是相反的。

這是一個例子:

@interface ListVC () {
    NSObject *objectA;
}
@property (nonatomic, strong) NSObject *objectB;
- (void)methodA;
@end

並在viewDidLoad中:

- (void)viewDidLoad {
    [super viewDidLoad];

    [self.tableView addPullToRefreshWithActionHandler:^{
        self.objectB = nil; //no warning here
        objectA = nil; //warning here
        [self methodA]; //warning here (if i place this above previous warning
    }];
}

第一個警告是正確的。 訪問塊中的實例變量將隱式保留self。 您沒有收到第二個語句警告的事實幾乎看起來像編譯器錯誤。

它看起來像編譯器只是不打擾多次警告你同一個塊。 我不確定這是一個功能,但我看不出還有什么可以發生。

假設我們使用相同的編譯器版本(我的是Apple LLVM 4.2),試試這個:

@interface Jubilee : NSObject

@property (copy, nonatomic) NSData * d;

@end

@implementation Jubilee
{
    NSString * s;
    dispatch_block_t block;
}

@synthesize d;

- (void)erase
{
    block = ^{
        s = @"Agamemnon";
    };

    block = ^{
        self.d = [NSData data];
    };

    block = ^{
        [self prevaricate];
    };

}

- (void)assemble
{
    block = ^{
        s = @"Agamemnon";
        self.d = [NSData data];
        [self prevaricate];
    };
}

- (void)prevaricate
{
}

@end

我在每個Block內部erase時都會收到警告,但僅限於Block中第一行的assemble 任何這些線路上的警告都是正確的。 當你對伊塔爾進行裸露的引用時,它隱含着self->ivar; 並且Block將保留self而不是ivar中的對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM