WebHU - Programozási kérdések és válaszok

Van-e valamilyen mód egy objektum zárolására a Swiftben, mint a C#-ban

A következő kódom van:

func foo() {
    var sum = 0
    var pendingElements = 10

    for i in 0 ..< 10 {
        proccessElementAsync(i) { value in
            sum += value
            pendingElements--

            if pendingElements == 0 {
                println(sum)
            }
        }
    }
}

Ebben az esetben a proccessElementAsync függvény, ahogy a neve is mutatja, aszinkron módon dolgozza fel a bemeneti paraméterét, és amikor befejezi, meghívja a megfelelő befejezési kezelőt.

Ennek a megközelítésnek az a kellemetlensége, hogy mivel a pendingElements változót több szálon keresztül érik el, lehetséges, hogy a if pendingElements == 0 utasításnak soha nem lesz igaz értéke.

C#-ban valami ilyesmit tudunk tenni:

Object lockObject = new Object();
...

lock (lockObject) {
    pendingElements--;

    if (pendingElements == 0) {
        Console.WriteLine(sum);
    }
}

és ez biztosítja, hogy ez a változó egyszerre csak egy szál számára lesz elérhető. Van valami mód arra, hogy ugyanezt a viselkedést elérje a Swiftben?

22.04.2015

  • mikeash.com/ pyblog/ 22.04.2015
  • Mellékes megjegyzés: a C#-ban a lock(someIntValue) nem tesz semmi olyat, ami közel áll ahhoz, amit el akarsz érni... C#-ban kérjük, vegye figyelembe az alapértelmezett irányelvet, amely szerint csak zárolás céljából hoz létre speciális objektumokat... 22.04.2015
  • C#-ban meg tudnánk csinálni Interlocked.Decrement 22.04.2015
  • A @Bas Interlocked.Decrement nem segít 2 változó védelmében – mint például a pendingElements és a sum, ahogy az ábrán látható. 22.04.2015
  • @AlexeiLevenkov Frissítettem a c# kódot, azt hiszem, túl informális voltam vele. Sajnálom, hogy 22.04.2015
  • @ReynaldoAguilar – most jól néz ki. Általában ne feledje, hogy az olvasók nem tehetnek különbséget az informális/gyorsan megírt minta és a fogalom teljes félreértése között. Tehát a helyesen kinéző kód megjelenítése jelentősen javítja annak esélyét, hogy a válasz valóban megkeresse azt, amit keres. 22.04.2015

Válaszok:


1

Remélhetőleg ez segíteni fog neked.

func lock(obj: AnyObject, blk:() -> ()) {
    objc_sync_enter(obj)
    blk()
    objc_sync_exit(obj)
}

var pendingElements = 10

func foo() {
    var sum = 0
    var pendingElements = 10

    for i in 0 ..< 10 {
        proccessElementAsync(i) { value in

            lock(pendingElements) {
                sum += value
                pendingElements--

                if pendingElements == 0 {
                    println(sum)
                }
            }

        }
    }
}
22.04.2015
  • Köszönjük válaszát. Ha az objc_sync_enter(obj) és az objc_sync_exit hívások azt teszik, amit én hiszek, akkor a válaszod megoldja a problémámat. Hozzá tudna adni néhány részletet ezeknek a funkcióknak a funkciójáról? Úgy gondolom, hogy ez javítani fogja a válasz minőségét 22.04.2015
  • Megkaptam az objc_sync_enter és a kilépés információit az Apple dokumentumából. objc_sync_enter(id obj) : Kezdje el a szinkronizálást az 'obj'-n. Szükség esetén lefoglalja az 'obj'-hoz társított rekurzív pthread_mutex-et. int objc_sync_exit(id obj): A szinkronizálás befejezése az 'obj'-n. 22.04.2015
  • csak másoknak ajánlok egy robusztusabb verziót func synchronized(object:AnyObject!, @noescape _ closure: () throws -> ()) rethrows { objc_sync_enter(object) defer { objc_sync_exit(object) } try closure() } 08.02.2016
  • Tekintse meg a még általánosabb lehetőséget ebben a válaszban 08.02.2016
  • Ez egyszerű dolgokra kiváló, de ha a záron belül szeretne korai visszatérést végrehajtani, akkor nem teheti meg (a visszatérés csak a zár hatóköréből tér vissza, nem a foo() függvényből. Sajnálatos :-( 01.10.2018

  • 2

    Nincsenek natív zárolási eszközök, de vannak olyan megoldások, amelyeket ebben a SO kérdésben ismertetünk:

    Mi a Swift megfelelője az Objective-C @synchronized-nek?

    A válaszok egyikével létrehozhat egy függvényt:

        func synchronize(lockObj: AnyObject!, closure: ()->()){
            objc_sync_enter(lockObj)
            closure()
            objc_sync_exit(lockObj)
        }
    

    és akkor:

         func foo() {
            var sum = 0
            var pendingElements = 10
    
            for i in 0 ..< 10 {
                processElementAsync(i) { value in
    
                    synchronize(pendingElements) {
                        sum += value
                        pendingElements--
    
                        if pendingElements == 0 {
                            println(sum)
                        }
                    }
    
                }
            }
        }
    
    22.04.2015
    Új anyagok

    A rádiógomb ellenőrzött eseményének használata a jQueryben
    Ebben a cikkben látni fogjuk, hogyan kell dolgozni a jquery választógombbal ellenőrzött eseményeivel. A választógombok HTML gombok, amelyek segítenek kiválasztani egyetlen értéket egy csoportból...

    Körkörös függőségek megoldása terraformban adatforrásokkal – lépésről lépésre
    Mi az a körkörös függőségek Dolgozzunk egy egyszerű eseten, amikor az SQS-sor és az S3-vödör közötti körkörös függőség problémája van egy egymástól függő címkeérték miatt. provider..

    Miért érdemes elkezdeni a kódolást 2023-ban?
    01100011 01101111 01100100 01100101 — beep boop beep boop Világunk folyamatosan fejlődik a technológia körül, és naponta fejlesztenek új technológiákat a valós problémák megoldására. Amint..

    🎙 Random Noise #2  – Örökbefogadás és hit
    az analitika íratlan világának gondozása Szeretné, hogy ezek a frissítések a postaládájába kerüljenek? Iratkozzon fel itt . "Ha önvezető autókat gyártanak, akkor mi miért ne..

    A legrosszabb politika és prediktív modellek májátültetésre jelöltek számára az Egyesült Államokban
    A máj (vagy óangolul lifer) az emberi test legnehezebb belső szervére utal, amely csendesen működik a nap 24 órájában. Mit csinál a máj? 500 feladatot hajt végre a szervezet egészségének..

    5 webhely, amely 2022-ben fejleszti front-end fejlesztői készségeit
    Frontendmentor.io A tényleges projektek létrehozásával a Frontendmentor.io segítséget nyújt a front-end kódolási képességeinek fejlesztésében. A kódolást azután kezdheti meg, hogy..

    Mikor kell használni a Type-t az interfészhez képest a TypeScriptben?
    A TypeScript a JavaScript gépelt szuperkészlete, amely statikus gépelést ad a nyelvhez. Ez megkönnyíti a robusztus és karbantartható kód írását azáltal, hogy a hibákat a fordítási időben..