EnumerateObjectsUsingBlock için BOOL * durdurma bağımsız değişkeni nedir: ne için kullanılır?


87

enumerateObjectsUsingBlock:Hızlı numaralandırma ihtiyaçlarım için son zamanlarda çok kullanıyorum BOOL *stopve numaralandırma bloğundaki kullanımını anlamakta zorlanıyorum .

NSArraySınıf referans durumları

stop: Bir Boolean değerine referans. Blok YES, dizinin daha fazla işlenmesini durdurmak için değeri ayarlayabilir . Bu stopargüman, salt olmayan bir argümandır. Bu Boole değerini yalnızca YESBlok içinde ayarlamalısınız .

Bu yüzden elbette numaralandırmayı durdurmak için bloğuma aşağıdakileri ekleyebilirim:

if (idx == [myArray indexOfObject:[myArray lastObject]]) {
    *stop = YES;
}

Ben söylemek mümkün oldum kadarıyla, açıkça kurmadığını *stopiçin YESherhangi bir olumsuz yan etkisi yoktur. Numaralandırma, dizinin sonunda otomatik olarak durur. Öyleyse kullanmak *stopgerçekten bir blokta gerekli mi?

Yanıtlar:


156

stopBlok bağımsız değişken numaralandırma durdurmak için izin verir zamanından önce . breakNormal bir fordöngünün eşdeğeridir . Dizideki her nesnenin üzerinden geçmek istiyorsanız bunu göz ardı edebilirsiniz.

for( id obj in arr ){
    if( [obj isContagious] ){
        break;    // Stop enumerating
    }

    if( ![obj isKindOfClass:[Perefrigia class]] ){
        continue;    // Skip this object
    }

    [obj immanetizeTheEschaton];
}

[arr enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    if( [obj isContagious] ){
        *stop = YES;    // Stop enumerating
        return;
    }

    if( ![obj isKindOfClass:[Perefrigia class]] ){
        return;    // Skip this object
    }

    [obj immanentizeTheEschaton];
}];

Bu bir çıkış parametresidir çünkü çağıran kapsamdaki bir değişkene referanstır. Bloğunuzun içinde ayarlanması gerekir, ancak içinde okunması gerekir enumerateObjectsUsingBlock:, aynı şekilde NSErrorçerçeve çağrılarından kodunuza geri gönderilir.

- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block {
    // N.B: This is probably not how this method is actually implemented!
    // It is just to demonstrate how the out parameter operates!

    NSUInteger idx = 0;
    for( id obj in self ){

        BOOL stop = NO;

        block(obj, idx++, &stop);

        if( stop ){
            break;
        }
    }
}

21
stopBayrağın tavsiye niteliğinde olduğuna dikkat edin ; numaralandırma, örneğin eşzamanlı durumda bazı tanımlanmamış sayıda yineleme için devam edebilir. Yani __block, numaralandırmanın her geçişinde koşulsuz olarak bir değişken ayarlamamalı ve stoperken sonlandırmak için kullanırken bunun "son" değer olmasını beklememelisiniz . Her zaman "hayır, bu nesneyi kullan" seçeneğini ayar ile birleştirmelisiniz stop = YES;.
bbum

@bbum, devam eden davranışın yalnızca eşzamanlı numaralandırma için geçerli olup olmadığını netleştirebilir misiniz ? Bu durumda tamamen anlaşılabilir olsa da, belgelenmemiştir ve "seri" sayım için oldukça şaşırtıcı bir ısırık olacaktır.
jscs

4
<rdar: // problem / 15015199> artık dokümantasyon her iki yolu da söylemediği ve yapması gerektiği için açıklama istiyor.
bbum
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.