[英]class method where self if used within a block
我有一個使用dispatch_once
創建靜態對象的類方法。 里面dispatch_once
塊我用[self class]
,並想知道如果我需要使用一個弱引用self
,以避免保留周期?
+ (NSArray *)accountNames{
static NSArray *names = nil;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
names = [[[self class] accounts] allKeys];
names = [names sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
});
return names;
}
如果我使用弱引用self
我會收到警告:
+ (NSArray *)accountNames{
static NSArray *names = nil;
static dispatch_once_t predicate;
__weak TUAccount *wself = self;
dispatch_once(&predicate, ^{
names = [[[wself class] accounts] allKeys];
names = [names sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
});
return names;
}
不兼容的指針類型使用類型為'const Class'的表達式初始化'TUAccount * __ weak'
因為我得到了一個警告,我認為在這種情況下我不需要使用對self
的弱引用,但我想看看你們的想法。
這里沒有理由擔心保留周期,因為保留或釋放類對象沒有意義 - 保留和釋放根本沒有效果。
您嘗試進行弱引用是錯誤的,因為您正在將類對象self
並嘗試將其轉換為TUAccount
的實例 。 這兩者是完全不同的東西。
此外,您可以簡化:
names = [[[self class] accounts] allKeys];
由於self已經是一個類,[self class] == self,所以這樣做:
names = [[self accounts] allKeys];
我已經再次檢查了iOS SDK Docs並找到了下一個:
Objective-C對象
在手動引用計數環境中,復制塊時將保留塊中使用的局部變量。 在塊中使用實例變量將導致保留對象本身。 如果要為特定對象變量覆蓋此行為,可以使用__block存儲類型修飾符對其進行標記。
如果使用ARC,則會在復制塊並稍后釋放時自動保留和釋放對象變量。
- 注意:在垃圾收集環境中,如果同時將__weak和__block修飾符應用於變量,則該塊將無法確保它保持活動狀態。
如果在方法的實現中使用塊,則對象實例變量的內存管理規則更加微妙:
- 如果通過引用訪問實例變量,則保留self;
- 如果按值訪問實例變量,則保留變量。
以下示例說明了兩種不同的情況:
dispatch_async(queue, ^{
// instanceVariable is used by reference, self is retained
doSomethingWithObject(instanceVariable);
});
id localVariable = instanceVariable;
dispatch_async(queue, ^{
// localVariable is used by value, localVariable is retained (not self)
doSomethingWithObject(localVariable);
});
結論:我認為在塊中使用self
沒有問題。 它將被保留並在執行后釋放。
此外,您不是將塊存儲在內存中並直接使用它。 因此它被復制到堆中,執行並從中推送。 我沒有看到任何保留周期。
希望我是對的!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.