2012-11-27 22 views
11

'daki tam kapsamdan kaçınmam gereken blok kalıplarını bilmiyorum Apple'ın belgelerinde şöyle denir: Bir blok değişmezi (yani,^{...}) bir adresin adresidir. Bloğu temsil eden yığın-yerel veri yapısı. Yığın-yerel veri yapısının kapsamı aşağıdaki örneklerde gösterildiği desenleri kaçınmalısınız, böylece bu nedenle çevreleyen birleşik deyimdir:Nesne-c

void dontDoThis() { 

    void (^blockArray[3])(void); // an array of 3 block references 

    for (int i = 0; i < 3; ++i) { 

     blockArray[i] = ^{ printf("hello, %d\n", i); }; 

     // WRONG: The block literal scope is the "for" loop. 
    } 

    //for example I invoke the block here 
    blockArray[1](); 
    } 


void dontDoThisEither() { 

    void (^block)(void); 

    int i = random(): 

    if (i > 1000) { 

     block = ^{ printf("got i at: %d\n", i); }; 

     // WRONG: The block literal scope is the "then" clause. 

    } 

    // ... 

    } 

ben kaçınmalısınız ne desen bilmiyorum. Örneğin, "if" veya "for" ifadesinin ardında, blok tanımıyla aynı genel kapsamı olan bloğu çağırmak gibi görünüyor. Açıklamama yardım eder misiniz?

İşte ben işaretçiler bir benzetme aşağıdaki gibidir düşünüyorum bağlantı https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Blocks/Articles/bxUsing.html#//apple_ref/doc/uid/TP40007502-CH5-SW1

cevap

9

olduğunu.

void foo() { 
    int *block = NULL; 
    { 
    int a; 
    block = &a; 
    } 
    // `block`, even though defined here, points to 
    // an invalid memory address. 
} 

Genellikle, kendisi değişmez blok sadece tanımlanan blokta bulunmaktadır, bu nedenle bu bloğu ayrılırken, edebi kaybolur (değişken a gibi yukarıdaki örnekte yaptığımız) ve sol konum sarkan bir işaretçi.

Bu nedenle, bloklar genellikle ileride kullanmak üzere yığına kopyalanır. ARC olmayan kod block_copy ve arkadaşları kullanır. Yığına kopyalamak, aynı zamanda, bloğunuzun kullandığı tüm ilgili değişkenleri de yakalar (tutma döngüleri yaratabilir).

Uygulamada, tüm bunlar ARC, özellikleri ve sınıfları kullanılarak tamamen terkedilmiştir. Sınıfınızda bir copy özelliğini tanımlar ve sonra sadece blokları atarsınız. Derleyicinin alıcı/ayarlayıcıyı oluşturmasına izin verirseniz, blok hazırlığınız otomatik olarak yığına kopyalanır.

@interface Bla : NSObject 
@property (nonatomic, copy) void (^blockProperty)(int i); 
@endf 

... 

Bla *bla = [[Bla alloc] init]; 
{ 
    bla.blockProperty = ^(int i) { printf("%d", i); }; 
} 
// bla.blockProperty now points to a heap copy of the block literal from above, 
// so it's not dangling. 
+0

Teşekkür ederiz. Ve demek oluyor ki blok, yöntemde bir yığın değişkeni yerine, kopyalanmış bir özellik olarak bildirilmelidir? –

+0

veya bir genel değişken olarak bir blok bildirebilir miyim? Aslında, her yerde görülen yerel yığında da saklanmalıdır. –

+0

Anladım! Çok teşekkür ederim. Blok bileşik deyimi, yığın yerel veri yapısının adresi olarak büyük ölçüde tamsayı bir değerden hoşlanır. –

0

Ben bloklar üzerinde elma belgeleri okuyarak ve bu bölümünde biraz daha araştırma yaptım oldu. ARC ile bana görünüyor, ikinci örnek kod tamamen iyi. İlk örneği denemedim. Kabul edilen cevaptaki genel fikir doğrudur. Ancak, ARC ile, literal bloğu (NSStackBlock) bir yerel değişkene atadığınızda, blok yığına kopyalanır ve bloğu incelerseniz gerçekten bir NSMallocBlock olduğunu görürsünüz. Bu konuyla ilgili de bu blogu referans olarak görmüştüm https://www.cocoawithlove.com/2009/10/how-blocks-are-implemented-and.html