2012-04-09 45 views
3

我碰到使用^在Objective-C塊的一些問題。我試圖從一個塊內設置一個實例變量 - 我已經閱讀了關於該主題的一些Apple文檔,並且我覺得我已經嘗試了一切。從^塊訪問屬性導致愚蠢的行爲

@interface MyClass 
{ 
    // I have tried all possible combinations using __weak, __strong and __block. 
    __weak __block NSMutableArray *filenames; 
} 

// *.m 
static ASIFormDataRequest *g_request = nil; 

@implementation MyClass 
-(void) funnymethod 
{ 
    filenames = [NSMutableArray array]; 
    [filenames addObject:@"This is a string."]; 
    NSLog(@"%@", filenames); 

    g_request = [InitializerClass initializeRequest]; 
    [g_request setCompletionBlock:^ 
    { 
     filenames = [NSMutableArray array]; 
     [filenames addObject:@"This is another string."]; 
     NSLog(@"%@", filenames); 
    }]; 

    [g_object startASynchronous]; 
} 
@end 

上面的代碼給出以下輸出: ( 「這是一個字符串。」) (空)

即吸收。所以,我已經試過__weak的不同組合,__strong和__block - 和其他任何給出了下面的輸出: (「這是一個字符串。」) (「這是另一個字符串。」) BUT!有一個巨大的但是。完成塊從不退出。頂部欄中指示打開連接的活動指示器不斷旋轉,屏幕變得無法響應。

如何設置文件名對象從成功的塊中?提前致謝。

+0

如果您的完成塊完全空白,會發生什麼情況?我認爲ASIFormDataRequest沒有完成的問題與你在這個塊中做什麼無關。 – 2012-04-09 16:02:44

回答

4

什麼預選賽做:

__block這個限定詞允許關閉修改存儲在給定變量的值。

__weak是對象的引用,不是防止對象被解除分配。

__strong是對確實對象的引用防止對象被解除分配。

你需要做的:

__weak你想要的東西,因爲它沒有阻止你的陣列被取消分配的電流範圍結束後沒有做。由於您正在進行異步調用,因此在執行塊之前沒有任何操作可以阻止恢復陣列使用的內存。

__strong將保留對象過去當前範圍的端部。這是你想要的。

__block將允許您的塊修改指定的變量,但在引用實例變量時不需要,因爲self將自動保留。

在引用計數的環境中,默認情況下,當您在塊中引用一個 Objective-C對象時,它將被保留。如果您只是引用對象的實例變量,即使是 也是如此。對象標有__block存儲類型改性劑 變量,然而,是 不保留。

注意:在垃圾收集環境中,如果將__weak和 __block修飾符同時應用於某個變量,則塊將不會確保它保持活動狀態。如果使用的是 方法的實現內的塊,對於對象的實例變量的存儲器管理的規則 是更微妙:

如果通過參考訪問實例變量,自被保持;

我認爲你的問題就出在這裏(相關部分在大膽):

您可以指定一個導入的變量是可變的,也就是說,通過應用__block讀直寫存儲類型修改器。 __block存儲與局部變量的寄存器,自動和靜態存儲類型相似,但相互排斥。

__block變量存在於變量的詞法範圍和所有聲明的塊或塊副本之間共享,或者在變量的詞法範圍內創建。因此,存儲將 生存的堆棧幀的破壞,如果幀中聲明塊 的任何副本生存超過框架的端部(對於 例如,通過被某處排隊以供以後執行)。在給定詞彙範圍內的多個 塊可以同時使用共享的 變量。

作爲一種優化,塊存儲開始了對堆疊就像 塊本身做。如果使用Block_copy複製塊(或在塊發送副本時位於Objective-C中),則會將變量複製到堆中的 。因此,__block變量的地址可以在 之間變化。

上有__block變量兩個另外的限制:它們不能 是可變長度數組,並且不能是含有C99 可變長度數組結構。

相反的NSMutableArray,請嘗試使用普通NSArray使用

+ (id)arrayWithObject:(id)anObject

+0

「可變長度數組」在[這個文檔】(https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Blocks/Articles/bxVariables.html#//apple_ref/doc/uid/TP40007502 -CH6-SW1)並不意味着「NSMutableArray」,它意味着[「C99可變長度數組」](http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html)。你可以有一個'__block NSMutableArray *'。 (這可能沒有意義,但它是允許的。) – 2012-04-09 15:54:41

+0

@ KurtRevis刪除。 – mydogisbox 2012-04-09 16:05:23

+0

你不需要'__block'來改變伊娃。對ivars的訪問通過隱含的'self'變量,由該塊複製。塊有效地執行'self-> fileNames = newValue'。 – 2012-04-09 16:08:22