2011-01-06 23 views
11

我想了解如何在iOS上使用塊。我已經閱讀過蘋果公司的文檔,但像往常一樣,它們含糊不清,並且沒有提到幾個關鍵信息。我也搜索了沒有成功。這是我正在嘗試做的一項練習來理解這一點。試圖瞭解iOS上的塊

我已經創建了一個塊來讀取一個字符串,並將字符串與先前的讀取進行比較。如果字符串不相同,則返回YES,如果它們相同,則返回NO。

這是我如何做:

我宣佈這對.H

BOOL (^differentStrings)(void); 

我在的viewController

__block NSString * previousString; 
__block NSString * currentString; 
differentStrings = ^(void){ 

    currentString = [self getString]; 
    NSLog(@"%@", currentString); // not printing anything on console 

    if (![currentString isEqualToString:previousString]) { 
     previousString = currentString; 
     return YES; 
    } else { 
     return NO; 
    } 
}; 

宣佈這對.M,裏面viewDidLoad中這是怎麼了我使用:我有一個線程可以做到這一點:

if (differentStrings) 
    NSLog (@"strings are different); 

這是我的問題:

  1. 塊總是返回YES(字符串不同)
  2. 我不舒服,宣佈這裏面videDidLoad。我應該如何聲明這一點,所以我可以在全球範圍內使用它作爲一種方法?我應該把這個像我會用一種方法嗎?
  3. 我在塊內調用一個方法「getString」。可以嗎?
  4. 我發現奇怪的是在.m上聲明塊變量。正如我所看到的,我應該在.h上聲明塊變量,然後在.m上使用它們。我試圖做到這一點,但收到了一個錯誤。
  5. 我已經在塊的第一行設置了一個調試點,但它並沒有停在那裏;
  6. 塊內的NSlog行不打印任何東西。是不是被稱爲塊?

你們能幫我解決嗎?

回答

15

你誤解了塊如何工作。 (好吧,所以這很明顯。)以與previousString是指向NSString的變量相同的方式,differentStrings是指向的變量。不是運行塊的結果,而是塊的本身。也就是說,你這樣做後:

__block NSString * previousString; 
__block NSString * currentString; 
differentStrings = ^(void){ 

    currentString = [self getString]; 
    NSLog(@"%@", currentString); // not printing anything on console 

    if (![currentString isEqualToString:previousString]) { 
     previousString = currentString; 
     return YES; 
    } else { 
     return NO; 
    } 
}; 

differentStrings是一個變量指向。因此,當你這樣做:

if (differentStrings) 

...你只是檢查是否differentStrings包含的東西除0或NULL以外。由於它包含一個塊,它不是空的,所以它的計算結果爲真。

切記:differentStrings是塊變量,而不是BOOL變量。它包含一個塊(如果你願意的話),當調用時會返回一個布爾值。因此,爲了實際運行該塊,您需要調用它。就像這樣:

differentStrings(); 

,或者在你的情況:

if (differentStrings()) { 
    NSLog (@"strings are different"); 
} 

編輯:正如在評論中指出,由於differentStrings是一個實例變量,你需要copy它,就像你在任何其他分配給實例變量的對象上調用retain。 (由於技術原因,我現在不會進入,您應該始終使用copy而不是retain)。同樣,您需要稍後調用release,也許在您的dealloc方法中。

3

,直到我看到Block和MulithreadingStanfords Developing Apps for iOS

+0

感謝一個很好的介紹,該錄像帶幫助理解它更深,但即使在看完之後我仍然有同樣的問題,這個階級也沒有提到。 – SpaceDog 2011-01-06 14:02:15

4

我不相信你實際上是在執行塊我不能讓我的周圍塊的頭。我認爲你的代碼應該是

if (differentStrings()) 
{ 
    NSLog (@"strings are different); 
} 

將一個塊視爲一個函數。我想你只是在檢查塊是否已被定義,而不是執行它。另外,如果您不需要訪問塊外部的NSString,則可以去掉__block限定符,並在塊內部移動currentString聲明。

如果您需要其他資源塊,我會在我的高級iOS開發課程on iTunes U的秋季課程中介紹它們。我在Understanding Cocoa會話中描述塊語法,以及它們在多線程會話中的Grand Central Dispatch中的使用。課程筆記還有一些示例應用程序的鏈接,這些應用程序以不同方式使用塊。

我也不能推薦的足夠高,你看WWDC 2010視頻會議206 - 在iPhone和211上推出塊和大中央調度 - 用大中央調度簡化iPhone應用程序開發。

+0

`previousString`需要是`__block`變量,因爲它的值在塊的後續調用之間被引用。此外,該塊需要在分配給伊娃時被複制,否則它將超出範圍。 – 2011-01-06 17:38:16

+1

@丹尼爾 - 好點,我會誤解他是如何使用該字符串的。 – 2011-01-06 18:27:53

+0

感謝Brad,我會檢查出來。 – SpaceDog 2011-01-06 19:15:33