首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Swift中创建线程安全数组

在Swift中创建线程安全数组
EN

Stack Overflow用户
提问于 2015-01-28 19:26:46
回答 16查看 60.9K关注 0票数 87

我在Swift中遇到线程问题。我有一个数组,里面有一些对象。通过委托,这个类几乎每秒都会获得新的对象。在这之后,我必须检查对象是否已经在数组中,所以我必须更新对象,否则我必须删除/添加新对象。

如果我添加一个新对象,我必须首先通过网络获取一些数据。这是通过积木的handelt。

现在我的问题是,如何同步这些任务?

我已经尝试了一个dispatch_semaphore,但是这个阻塞了UI,直到这个阻塞结束。

我还尝试了一个简单的bool变量,它检查代码块当前是否正在执行,同时跳过compare方法。

但这两种方法都不理想。

管理阵列的最佳方法是什么,我不希望阵列中有重复的数据。

EN

Stack Overflow用户

发布于 2016-10-14 22:17:52

Kirsteins的答案是正确的,但为了方便起见,我用Amol Chaudhari和Rob的建议更新了这个答案,他们建议使用带有异步屏障的并发队列,以允许并发读取但阻止写入。

我还包装了一些对我有用的其他数组函数。

代码语言:javascript
运行
复制
public class SynchronizedArray<T> {
private var array: [T] = []
private let accessQueue = dispatch_queue_create("SynchronizedArrayAccess", DISPATCH_QUEUE_CONCURRENT)

public func append(newElement: T) {
    dispatch_barrier_async(self.accessQueue) {
        self.array.append(newElement)
    }
}

public func removeAtIndex(index: Int) {
    dispatch_barrier_async(self.accessQueue) {
        self.array.removeAtIndex(index)
    }
}

public var count: Int {
    var count = 0

    dispatch_sync(self.accessQueue) {
        count = self.array.count
    }

    return count
}

public func first() -> T? {
    var element: T?

    dispatch_sync(self.accessQueue) {
        if !self.array.isEmpty {
            element = self.array[0]
        }
    }

    return element
}

public subscript(index: Int) -> T {
    set {
        dispatch_barrier_async(self.accessQueue) {
            self.array[index] = newValue
        }
    }
    get {
        var element: T!

        dispatch_sync(self.accessQueue) {
            element = self.array[index]
        }

        return element
    }
}
}

更新这是相同的代码,针对Swift3进行了更新。

代码语言:javascript
运行
复制
public class SynchronizedArray<T> {
private var array: [T] = []
private let accessQueue = DispatchQueue(label: "SynchronizedArrayAccess", attributes: .concurrent)

public func append(newElement: T) {

    self.accessQueue.async(flags:.barrier) {
        self.array.append(newElement)
    }
}

public func removeAtIndex(index: Int) {

    self.accessQueue.async(flags:.barrier) {
        self.array.remove(at: index)
    }
}

public var count: Int {
    var count = 0

    self.accessQueue.sync {
        count = self.array.count
    }

    return count
}

public func first() -> T? {
    var element: T?

    self.accessQueue.sync {
        if !self.array.isEmpty {
            element = self.array[0]
        }
    }

    return element
}

public subscript(index: Int) -> T {
    set {
        self.accessQueue.async(flags:.barrier) {
            self.array[index] = newValue
        }
    }
    get {
        var element: T!
        self.accessQueue.sync {
            element = self.array[index]
        }

        return element
    }
}
}
票数 38
EN
查看全部 16 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28191079

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档