Lista Składni Deklaracji Blokowych

Składnia blokowa w Objective C (i rzeczywiście c, jak przypuszczam) jest notorycznie niezgodna. Przekazywanie bloków jako argumentów wygląda inaczej niż deklarowanie bloków jako ivars, co wygląda inaczej niż typedefING blocks.

Czy istnieje obszerna lista składni deklaracji blokowych, którą mógłbym mieć pod ręką w celu szybkiego odniesienia?

Author: Patrick Perini, 2012-02-09

7 answers

Lista składni deklaracji blokowych

W całym, niech

  • return_type być typem obiektu / prymitywnego / itd. chcesz wrócić (powszechnie void)
  • blockName być nazwą zmiennej bloku, który tworzysz
  • var_type być obiektem typu / primitive / etc. chcesz przekazać jako argument (pozostaw puste dla żadnych parametrów)
  • varName być nazwą zmiennej podanego parametru

I pamiętaj, że możesz stworzyć jak najwięcej parametry jak chcesz.

Bloki jako zmienne

Prawdopodobnie najbardziej powszechne dla deklaracji.

return_type (^blockName)(var_type) = ^return_type (var_type varName)
{
    // ...
};

Bloki jako właściwości

Podobnie jak deklarowanie bloków jako zmiennych, jednak subtelnie różne.

@property (copy) return_type (^blockName) (var_type);

Bloki jako parametry

Zauważ, że to różni się od "bloków jako argumentów"; w tym przypadku deklarujesz metodę, która chce argumentu blokowego.

- (void)yourMethod:(return_type (^)(var_type))blockName;

Bloki jako argumenty

Zauważ, że jest to inaczej niż "bloki jako parametry"; w tym przypadku wywołujesz metodę, która chce argumentu blokowego z anonimowym blokiem. Jeśli zadeklarowałeś już zmienną blokową, wystarczy podać nazwę zmiennej jako argument.

[someObject doSomethingWithBlock: ^return_type (var_type varName)
{
    //...
}];

Blok Anonimowy

Jest to funkcjonalnie blok anonimowy, jednak składnia przypisywania bloków do zmiennych polega po prostu na ustawieniu zmiennej równej anonimowemu blokowi.

^return_type (var_type varName)
{
    //...
};

typedef blok

To pozwala na skonfigurowanie krótkiej nazwy, do której można się odwoływać, tak jak każda inna nazwa klasy podczas deklaracji bloków.

typedef return_type (^blockName)(var_type);

Aby później użyć blockName zamiast standardowej składni deklaracji blokowej, po prostu zastąp.

Inline Block

Jest to prawdopodobnie mniej użyteczne wykorzystanie bloków, ale może mieć swoje miejsce. Blok wbudowany jest blokiem anonimowym wywoływanym natychmiast po utworzeniu instancji.

^return_type (var_type varName)
{
    //...
}(var);

Bloki Inline są przede wszystkim przydatne do kompensacji zakresu i są mniej więcej równoważne prostym fragmentom kodu oddzielonym nawiasami.

{
   //...
}

Bloki Rekurencyjne

To pozwala na wywołanie bloku z samego siebie, tworząc pętlę, która może być używana podczas wywołań zwrotnych i wywołań GCD. Ta metoda instancjacji jest wolna od cykli zatrzymywania w łuku.

__block return_type (^blockName)(var_type) = [^return_type (var_type varName)
{
    if (returnCondition)
    {
        blockName = nil;
        return;
    }

    // ...
} copy];
blockName(varValue);

Zwracanie Bloków

Metoda może zwrócić blok,

- (return_type(^)(var_type))methodName
{
    // ...
}

Jak może funkcja, jeśli trochę dziwnie.

return_type (^FunctionName())(var_type)
{
    // ...
}

Dodatki

Jeśli Przegapiłem coś, proszę dać mi znać w komentarzach, a ja je zbadam/dodam.

I to szybko...
blockName = (varName: var_type) -> (return_type)
To prawie jak funkcja językowa.
 683
Author: Patrick Perini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-08 02:57:51

Osobiście lubię korzystać z tej strony ( http://fuckingblocksyntax.com ). nazwa jest łatwiejsza do zapamiętania niż sama składnia bloku:

Http://fuckingblocksyntax.com

A jeśli nie możesz załadować adresów URL ze złymi słowami, możesz użyć tego mirrora: http://goshdarnblocksyntax.com

fuckingblocksyntax website

 76
Author: psy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-10 20:52:18

Typedef:

typedef void (^block)(NSString *arg);

Inline:

void (^block)(NSString *) = ^(NSString *param) {
  // do something....
};

Metoda:

- (void)method:(void (^)(NSString *param))handler
 37
Author: Erik Aigner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-08 21:22:00

Biblioteka fragmentów Xcode 4 zawiera szablony dla typów bloków i bloków wbudowanych jako zmienne. Są one również dostępne poprzez automatyczne uzupełnianie (typedefblock i inlineblock).

Dla bloków jako argumentów metod, zalecam zadeklarowanie typedef, a następnie po prostu użycie tego. To sprawia, że kod jest znacznie łatwiejszy do odczytania.

 16
Author: omz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-08 21:17:07

Napisałem completionBlock dla klasy, która zwróci wartości kości po ich wytrząsaniu:

  1. Zdefiniuj typedef za pomocą returnType (.h powyżej @interface deklaracji)

    typedef void (^CompleteDiceRolling)(NSInteger diceValue);
    
  2. Define a @property for the block (.h)

    @property (copy, nonatomic) CompleteDiceRolling completeDiceRolling;
    
  3. Zdefiniuj metodę z finishBlock (.h)

    - (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock;
    
  4. Wstaw previous defined method in .m file and commit finishBlock to @property defined before

    - (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock{
        self.completeDiceRolling = finishBlock;
    }
    
  5. To trigger completionBlock przekazuje do niego predefiniowany zmienny typ (Nie zapomnij sprawdzić, czy completionBlock istnieje)

    if( self.completeDiceRolling ){
        self.completeDiceRolling(self.dieValue);
    }
    
 10
Author: Alex Cio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-22 14:14:05
typedef void (^OkBtnBlock)(id data);
typedef void (^CancelBtnBlock)();

@property (nonatomic, strong) OkBtnBlock okBtnBlock;
@property (nonatomic, strong) CancelBtnBlock cancelBtnBlock;

+ (void)foo:(OkBtnBlock)okBtn andCancel:(CancelBtnBlock)btnCancel;
 6
Author: benhi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-25 12:23:08

Jeśli chcesz pracować z powrotem w Xcode 4.2, możesz również @ syntetyzować blok zadeklarowany jako właściwość, tak jak w przypadku właściwości nieblokującej. Nie pozwól, aby składnia blokowa Cię rzuciła.

Jeśli twoja własność blokowa jest taka:

@property (copy) return_type (^blockName) (var_type);

Wtedy twój @synthesize jest taki:

@property blockName;
Zdrówko.
 3
Author: Alex Zavatone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-15 17:37:38