Blok Bildirimi Sözdizimi Listesi


277

Objective C'deki (ve aslında C, sanırım) blok sözdizimi herkesin bildiği gibi uyumsuzdur. Blokları argüman olarak iletmek, blokları ivars olarak tanımlamaktan farklıdır, bu da typedefbloklardan farklı görünür .

Hızlı başvuru için elimde tutabileceğim kapsamlı bir blok bildirim sözdizimi listesi var mı?


9
Blok Programlama Konuları Kılavuzu'ndaki "Blokları Bildirme ve Oluşturma" ile ilgili sorun nedir ?
jscs

blok özelliklerini kullanmanın kolay açıklaması: stackoverflow.com/a/20760583/294884
Fattie

Yanıtlar:


696

Blok Bildirimi Sözdizimleri Listesi

Boyunca

  • return_typenesne türü / ilkel / vb. dönmek istiyorsunuz (yaygın olarak void)
  • blockName oluşturduğunuz bloğun değişken adı olun
  • var_typetür nesnesi / ilkel / vb. bağımsız değişken olarak geçmek istersiniz (parametre için boş bırakın)
  • varName verilen parametrenin değişken adı olmalı

Ve istediğiniz kadar parametre oluşturabileceğinizi unutmayın.

Değişken Olarak Bloklar

Beyan için muhtemelen en yaygın olanı.

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

Özellik Olarak Bloklar

Blokları değişken olarak bildirmeye benzer, ancak farklıdır.

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

Parametre Olarak Bloklar

Bunun "Bağımsız Değişken Blokları" ndan farklı olduğunu unutmayın; bu örnekte, blok bağımsız değişken isteyen bir yöntem bildiriyorsunuz.

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

Bağımsız Değişken Olarak Bloklar

Bunun "Parametreler Olarak Bloklar" dan farklı olduğunu unutmayın; bu örnekte, anonim bir bloğa sahip bir blok bağımsız değişkeni isteyen bir yöntem çağırıyorsunuz. Daha önce bir blok değişkeni bildirdiyseniz, değişken adını bağımsız değişken olarak iletmeniz yeterlidir.

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

Anonim Blok

Bu işlevsel olarak anonim bir bloktur, ancak değişkenlere blok atama sözdizimi basitçe değişkeni anonim bir bloğa eşit ayarlamaktır.

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

typedef Blok

Bu, blokların bildirimi sırasında herhangi bir sınıf adı gibi referans verilebilecek kısa bir ad ayarlamanızı sağlar.

typedef return_type (^blockName)(var_type);

Daha sonra blockNamestandart blok bildirimi sözdizimi yerine kullanmak için, sadece değiştirin.

Satır İçi Blok

Bu muhtemelen blokların daha az kullanışlı bir kullanımıdır, ancak yine de yerini alabilir. Satır içi bir blok, somutlaştırıldıktan hemen sonra çağrılan anonim bir bloktur.

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

Satır içi bloklar öncelikle kapsam dengelemesi için kullanışlıdır ve kabaca küme sınırlaması olan basit kod parçalarına kabaca eşdeğerdir.

{
   //...
}

Özyinelemeli Bloklar

Bu, geri aramalar ve GCD çağrıları sırasında kullanılabilecek bir döngü oluşturarak, kendisinden bir blok çağırmanıza izin verir. Bu örnekleme yönteminde ARC'de tutma döngüleri yoktur.

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

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

Dönen Bloklar

Bir yöntem bir bloğu döndürebilir,

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

biraz garip ise, bir fonksiyon gibi.

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

Ekler

Bir şey kaçırdıysam, lütfen yorumlarda bana bildirin, ben de araştırırım / ekleyeceğim

Ah, ve Swift'te ...

blockName = (varName: var_type) -> (return_type)

Neredeyse bir dil özelliği gibi.


1
@pcperini Harika bir liste! Değişken bildiriminde (listenizdeki 1. öğe) typedef'd blok tanımını nasıl kullanabilirsiniz? Mantıksal BlockType ^blockVar = Anonymous Block, ^ da olmadan sözdizimi hatası gösterir :(
esp

14
Bir şekilde beynim blok bildirimleri için tüm bu çeşitli sözdizimini hatırlayamıyor. Muhtemelen bu cevaba haftada bir bakıyorum. Bunun için size 10 oy verebilirim.
Ben Baron

36
Bunun gibi cevaplar için StackOverflow Onur Listesi'ne ihtiyacımız var.
bejonbee

1
Bunu yazdırmak için bir görüntüleyici ile kullanmak üzere Markdown'a dönüştürdüm. Kullanışlı! gist.github.com/swizzlr/6268955
Swizzlr

20
Sanırım buna dövme olarak ihtiyacım var.
Isaac Overacker


39

typedef:

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

Çizgide:

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

Yöntem:

- (void)method:(void (^)(NSString *param))handler

Bu cevap, sonuçta o kadar karmaşık olmadığını gösteriyor ... karıştırmak ve eşleştirmek için sadece 3 farklı sözdizimi.
Joseph Chen

4
Kabul edilen cevap, gereksiz cevaplar içeren bu cevabın sadece bir kopyasıdır.
Erik Aigner

16

Xcode 4 snippet kütüphanesi blok tip tanımları ve satır içi bloklar için değişkenler için şablonlar içerir. Ayrıca otomatik tamamlama ( typedefblockve inlineblock) ile de kullanılabilirler .

Yöntemler için argümanlar olarak bloklar için, bir typedefve daha sonra sadece bunu bildirmenizi öneririm . Kodun okunmasını çok daha kolay hale getirir.


11

Çalkalandıktan sonra bir zarın değerlerini döndürecek bir sınıf için bir completionBlock yazdım:

  1. Typedef'i returnType (tanımlamanın .hüstünde @interface) ile tanımlayın

    typedef void (^CompleteDiceRolling)(NSInteger diceValue);
  2. A @property( .h) bloğu için tanımla

    @property (copy, nonatomic) CompleteDiceRolling completeDiceRolling;
  3. finishBlock( .h) İle bir yöntem tanımlama

    - (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock;
  4. Önceki tanımlanan yönteme takın .mdosya ve taahhüt finishBlocketmek @propertyönce tanımlanmış

    - (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock{
        self.completeDiceRolling = finishBlock;
    }
  5. Tetiklemek için completionBlockönceden tanımlanmış bir değişkenTipi yazın (Var olup olmadığını kontrol etmeyi unutmayın completionBlock)

    if( self.completeDiceRolling ){
        self.completeDiceRolling(self.dieValue);
    }

7
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;

Tüm süreci adım adım açıklamak iyi olurdu, ios için yeni iseniz blokları anlamak zor ...
Alex Cio

3

Xcode 4.2'de tekrar çalışmanız gerekiyorsa, tıpkı blok olmayan bir özellikte olduğu gibi özellik olarak bildirilen bir bloğu da sentezleyebilirsiniz. Blok sözdiziminin sizi atmasına izin vermeyin.

Block özelliğiniz bu ise:

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

O zaman @synthesize'niz şudur:

@property blockName;

Şerefe.


Merhaba, lütfen tekrar kontrol eder misiniz .. Sadece seni takip etmeye çalışıyordum .. @property blockNameçalışmıyor. Bence öyle @synthesize blockName;mi? (bir bloğu sentezlemek için)
jeet.chanchawat

ayy ... bekle seni zaten (dolaylı olarak) xcode 7 ile çalışmayacağını söyledi
jeet.chanchawat
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.