你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> IOS block編程指南 5 Block和變量

IOS block編程指南 5 Block和變量

編輯:IOS開發綜合

Blocks and Variables(Block和變量)

This article describes the interaction between blocks and variables, including memory management.

本文講述了block和變量之間的內在關系,包括內存管理。

Types of Variable(變量類型)

Within the block object’s body of code, variables may be treated in five different ways.

You can reference three standard types of variable, just as you would from a function:

  • Global variables, including static locals

  • Global functions (which aren’t technically variables)

  • Local variables and parameters from an enclosing scope

    block對象中的代碼中,變量會被五種方法區別對待。 你可以參考三種標准變量,就像你在一個函數中那樣: 全局變量,包括靜態的本地變量全局函數,(這個並不是技術上的變量)本地變量,和同一個作用域的參數

    Blocks also support two other types of variable:

    1. At function level are __block variables. These are mutable within the block (and the enclosing scope) and are preserved if any referencing block is copied to the heap.

    2. const imports.

      Finally, within a method implementation, blocks may reference Objective-C instance variables—see Object and Block Variables.

      block也支持其他兩種類型的變量 在函數級別的_block 變量。這些變量在block中是可變的,同時如果引用變量的block拷貝進堆堆,手動管理內存)內存就會保存 。 常量 最後,隨著方法的實現,blocks會引用objective-C的實例變量——參見: Object and Block Variables。

      The following rules apply to variables used within a block:

      1. Global variables are accessible, including static variables that exist within the enclosing lexical scope.

      2. Parameters passed to the block are accessible (just like parameters to a function).

      3. Stack (non-static) variables local to the enclosing lexical scope are captured as const variables.

        Their values are taken at the point of the block expression within the program. In nested blocks, the value is captured from the nearest enclosing scope.

      4. Variables local to the enclosing lexical scope declared with the __block storage modifier are provided by reference and so are mutable.

        Any changes are reflected in the enclosing lexical scope, including any other blocks defined within the same enclosing lexical scope. These are discussed in more detail inThe __block Storage Type.

      5. Local variables declared within the lexical scope of the block, which behave exactly like local variables in a function.

        Each invocation of the block provides a new copy of that variable. These variables can in turn be used as const or by-reference variables in blocks enclosed within the block.

        以下規則適用於block中使用的變量: 全局變量可以訪問,包括作用域內的靜態變量。(這裡block有對全局變量的讀寫權限)傳入block中的參數可以訪問(就像函數中的參數)。作用域中的棧(自動內存管理)(非靜態)變量,被當做常量來使用。 在程序中他們的值被block表達式調用。在嵌套block中,會使用最近的作用域中的變量。(筆者的理解是,嵌套的只能用最近的。PS:這一大段其實就幾個字:block中普通變量是只讀的)作用域中的_block變量提供的是引用,所以是可變的。 所有的變動都會反映在作用域中,包括同一個作用域內定義了其他的block。更具體的討論:見The __block Storage Type。block中聲明的局部變量,他們的行為很像函數中的局部變量。 block的每次調用都會給變量提供一份新的拷貝。這些在block作用域中的變量可以是常量,也可以做變量(引用的)。

        The following example illustrates the use of local non-static variables:

        下列例子說明了非靜態局部變量變量的使用

        int x = 123;
         
        void (^printXAndY)(int) = ^(int y) {
         
            printf(%d %d
        , x, y);
        };
         
        printXAndY(456); // prints: 123 456

        As noted, trying to assign a new value to x within the block would result in an error:

        值得注意的是,試圖在塊內給block賦值會返回error

        int x = 123;
         
        void (^printXAndY)(int) = ^(int y) {
         
            x = x + y; // error
            printf(%d %d
        , x, y);
        };

        To allow a variable to be changed within a block, you use the __block storage type modifier—see The __block Storage Type.

        為了允許在block中修改變量,你需要用 _block 類型存儲 ,見:The __block Storage Type。

        The __block Storage Type(_block 存儲類型)

        You can specify that an imported variable be mutable—that is, read-write— by applying the __block storage type modifier. __block storage is similar to, but mutually exclusive of, the register, auto, and static storage types for local variables.

        __block variables live in storage that is shared between the lexical scope of the variable and all blocks and block copies declared or created within the variable’s lexical scope. Thus, the storage will survive the destruction of the stack frame if any copies of the blocks declared within the frame survive beyond the end of the frame (for example, by being enqueued somewhere for later execution). Multiple blocks in a given lexical scope can simultaneously use a shared variable.

        As an optimization, block storage starts out on the stack—just like blocks themselves do. If the block is copied using Block_copy (or in Objective-C when the block is sent a copy), variables are copied to the heap. Thus, the address of a __block variable can change over time.

         

        There are two further restrictions on __block variables: they cannot be variable length arrays, and cannot be structures that contain C99 variable-length arrays.



        你可以指定一個輸入的變量是可變的,(可以讀,寫),通過使用_block存儲類型修飾符。_block很類似,(但是區別於),局部變量的 register,auto,stack,存儲類型。 _block變量生存的存儲范圍,是變量的作用域和所有block和block的拷貝聲明的或者創造的作用域。因此呢,如果block的一個拷貝聲明在一個沒有被銷毀的框架裡面,存儲會在棧內存銷毀時不被銷毀,直到這個框架結束(舉例,被排到某處,延後執行)。同一作用域下的多個block可以共同使用一個變量。 作為優化,block存儲從棧開始——就像block他們自己在做。如果block使用Block_copy(或Objective-C,當block發送出一份拷貝的時候),變量拷貝到堆(手動內存管理)。這樣_block變量就可以隨時改變地址了。 對於_block變量有兩個更進一步的約束:他們不能作為變長數組,不能成為包含C99數組的結構。

        The following example illustrates use of a __block variable:

        下面的例子說說明了_block變量的使用。

        __block int x = 123; //  x lives in block storage
         
        void (^printXAndY)(int) = ^(int y) {
         
            x = x + y;
            printf(%d %d
        , x, y);
        };
        printXAndY(456); // prints: 579 456
        // x is now 579

        The following example shows the interaction of blocks with several types of variables:

        這個例子展現了幾種類型的block的相互作用

        extern NSInteger CounterGlobal;
        static NSInteger CounterStatic;
         
        {
            NSInteger localCounter = 42;
            __block char localCharacter;
         
            void (^aBlock)(void) = ^(void) {
                ++CounterGlobal;
                ++CounterStatic;
                CounterGlobal = localCounter; // localCounter fixed at block creation
                localCharacter = 'a'; // sets localCharacter in enclosing scope
            };
         
            ++localCounter; // unseen by the block 
            localCharacter = 'b';
         
            aBlock(); // execute the block
            // localCharacter now 'a'
        }

        Object and Block Variables (對象和block變量)


        Blocks provide support for Objective-C and C++ objects, and other blocks, as variables.

        block可以作為變量,支持Objective-C和C++對象,其他block。

        Objective-C Objects(Objective—C 對象)

        When a block is copied, it creates strong references to object variables used within the block. If you use a block within the implementation of a method:

        • If you access an instance variable by reference, a strong reference is made to self;

        • If you access an instance variable by value, a strong reference is made to the variable.

          當一個block被拷貝了,他創建一個對block中使用的對象變量的強引用。如果你在塊內實現了一個方法: 如果你通過引用訪問一個實例變量,就對self建立一個強引用。如果你通過值訪問了一個實例變量,就對變量建立一個強引用。

          The following examples illustrate the two different situations:

          下面的例子說明了不同的情況

          dispatch_async(queue, ^{
              // instanceVariable is used by reference, a strong reference is made to self
              doSomethingWithObject(instanceVariable);
          });
           
           
          id localVariable = instanceVariable;
          dispatch_async(queue, ^{
              /*
                localVariable is used by value, a strong reference is made to localVariable
                (and not to self).
              */
              doSomethingWithObject(localVariable);
          });

          To override this behavior for a particular object variable, you can mark it with the __block storage type modifier.

          通過重寫一個特定對象變量,你可以使用_block存儲類型修飾符來標記它。

           

          C++ Objects (C++對象)

          In general you can use C++ objects within a block. Within a member function, references to member variables and functions are via an implicitly imported this pointer and thus appear mutable. There are two considerations that apply if a block is copied:

          • If you have a __block storage class for what would have been a stack-based C++ object, then the usual copy constructor is used.

          • If you use any other C++ stack-based object from within a block, it must have a const copy constructor. The C++ object is then copied using that constructor.

            通常情況下你可以在C++對象中使用block。在一個成員函數中,對成員變量和函數的引用通過一個隱晦的this指針實現,然後就出現了變數。如果一個block申請拷貝,這裡有兩種情況考慮: 如果你有一個基於棧的C++對象,裡面有_block存儲類,這個時候使用通常構造函數。如果你在一個block中使用其他的基於棧的C++對象,就必須使用常拷貝構造函數。C++對象拷貝的時候會用那個構造函數。

             

             
             
  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved