Arrays 关联对象和Swift数组
我在视图扩展上有一个关联的对象,它包含一个数组(在本例中是一个可变数组)Arrays 关联对象和Swift数组,arrays,objective-c,swift,nsmutablearray,associated-object,Arrays,Objective C,Swift,Nsmutablearray,Associated Object,我在视图扩展上有一个关联的对象,它包含一个数组(在本例中是一个可变数组) 我想将NSMutableArray转换为Swift数组,但我不知道该怎么做。这将阻止我执行相当丑陋的铸造。有什么建议吗 NSMutableArray这里是一个引用类型。这样做的结果是,当您向某人提供对视图对象的队列的引用时,您的视图对象将失去对它的所有控制。引用的接收者可以重新排列项目、删除所有项目等,而您的视图只有在下次尝试阅读时才会知道 一般来说,这种隐式数据共享被认为是一个坏主意,因为它破坏了封装,使系统复杂化,因为
我想将
NSMutableArray
转换为Swift数组,但我不知道该怎么做。这将阻止我执行相当丑陋的铸造。有什么建议吗 NSMutableArray这里是一个引用类型。这样做的结果是,当您向某人提供对视图对象的队列的引用时,您的视图对象将失去对它的所有控制。引用的接收者可以重新排列项目、删除所有项目等,而您的视图只有在下次尝试阅读时才会知道
一般来说,这种隐式数据共享被认为是一个坏主意,因为它破坏了封装,使系统复杂化,因为您无法再对代码进行局部推理,因为总是存在另一个线程引用您的别名对象并在您脚下更改它的威胁
此模型与Swift的值类型不兼容,例如Array
。如果队列
是一个数组
,则访问它的每个人都将返回自己的值。从语义上讲,这些拷贝都是彼此完全隔离的,通过一个引用进行的突变无法引起通过另一个引用可以观察到的效果
如果希望忠实地保留当前代码的引用语义,则需要一种机制来侦听对NSMutableArray
的更改,并更新从中派生的每个数组
。这并不实际,也不是一个好主意
下面是我要做的:
使接口更显式地具有事务性。更有可能的是,您可以完全隐藏队列
。将其设置为私有,并让您的视图公开公共方法,如push
和pop
import Foundation
class C: NSObject {
private enum AssociatedObjectKeys {
static var queue: Int8 = 0
}
private var queue: Array<Int> {
get {
guard let existingValue = objc_getAssociatedObject(self, &AssociatedObjectKeys.queue) else {
self.queue = []
return []
}
guard let existingArray = existingValue as? Array<Int> else {
fatalError("Found an associated object that had the wrong type!")
}
return existingArray
}
set {
objc_setAssociatedObject(self, &AssociatedObjectKeys.queue, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
public func printQueueForDebugging() {
print(self.queue)
}
public func push(_ newValue: Int) {
self.queue.append(newValue)
}
public func pushAll<S: Sequence>(_ newValues: S) where S.Element == Int {
self.queue.append(contentsOf: newValues)
}
public func pop() -> Int? {
if self.queue.isEmpty { return nil }
return self.queue.removeFirst()
}
}
let c = C()
c.printQueueForDebugging()
c.pushAll(1...3)
c.printQueueForDebugging()
c.push(4)
c.printQueueForDebugging()
print(c.pop() as Any)
print(c.pop() as Any)
print(c.pop() as Any)
print(c.pop() as Any)
print(c.pop() as Any)
<代码>导入基础
C类:NSObject{
私有枚举关联的ObjectKey{
静态变量队列:Int8=0
}
私有变量队列:数组{
得到{
guard let existingValue=objc_getAssociatedObject(self,&AssociatedObjectKeys.queue)else{
self.queue=[]
返回[]
}
guard let existingArray=existingValue as?Array else{
fatalError(“找到了类型错误的关联对象!”)
}
返回现有数组
}
集合{
objc_setAssociatedObject(self,&AssociatedObjectKeys.queue,newValue,.objc_ASSOCIATION_RETAIN_NONATOMIC)
}
}
公共函数printQueueForDebugging(){
打印(self.queue)
}
公共函数推送(\uNewValue:Int){
self.queue.append(newValue)
}
公共func pushAll(newValues:S),其中S.Element==Int{
self.queue.append(contentsOf:newValues)
}
公共函数pop()->Int{
如果self.queue.isEmpty{return nil}
返回self.queue.removeFirst()
}
}
设c=c()
c、 printQueueForDebugging()
c、 普沙尔(1…3)
c、 printQueueForDebugging()
c、 推(4)
c、 printQueueForDebugging()
打印(c.pop()如有)
打印(c.pop()如有)
打印(c.pop()如有)
打印(c.pop()如有)
打印(c.pop()如有)
队列
数据结构<代码>数组本身并不构成一个好的队列,因为从一开始删除就具有时间复杂度O(n)
。有很多数据结构库,我会使用它们的一个队列NSMutableArray
这里是一个引用类型。这样做的结果是,当您向某人提供对视图对象的队列的引用时,您的视图对象将失去对它的所有控制。引用的接收者可以重新排列项目、删除所有项目等,而您的视图只有在下次尝试阅读时才会知道
一般来说,这种隐式数据共享被认为是一个坏主意,因为它破坏了封装,使系统复杂化,因为您无法再对代码进行局部推理,因为总是存在另一个线程引用您的别名对象并在您脚下更改它的威胁
此模型与Swift的值类型不兼容,例如Array
。如果队列
是一个数组
,则访问它的每个人都将返回自己的值。从语义上讲,这些拷贝都是彼此完全隔离的,通过一个引用进行的突变无法引起通过另一个引用可以观察到的效果
如果希望忠实地保留当前代码的引用语义,则需要一种机制来侦听对NSMutableArray
的更改,并更新从中派生的每个数组
。这并不实际,也不是一个好主意
下面是我要做的:
使接口更显式地具有事务性。更有可能的是,您可以完全隐藏队列
。将其设置为私有,并让您的视图公开公共方法,如push
和pop
import Foundation
class C: NSObject {
private enum AssociatedObjectKeys {
static var queue: Int8 = 0
}
private var queue: Array<Int> {
get {
guard let existingValue = objc_getAssociatedObject(self, &AssociatedObjectKeys.queue) else {
self.queue = []
return []
}
guard let existingArray = existingValue as? Array<Int> else {
fatalError("Found an associated object that had the wrong type!")
}
return existingArray
}
set {
objc_setAssociatedObject(self, &AssociatedObjectKeys.queue, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
public func printQueueForDebugging() {
print(self.queue)
}
public func push(_ newValue: Int) {
self.queue.append(newValue)
}
public func pushAll<S: Sequence>(_ newValues: S) where S.Element == Int {
self.queue.append(contentsOf: newValues)
}
public func pop() -> Int? {
if self.queue.isEmpty { return nil }
return self.queue.removeFirst()
}
}
let c = C()
c.printQueueForDebugging()
c.pushAll(1...3)
c.printQueueForDebugging()
c.push(4)
c.printQueueForDebugging()
print(c.pop() as Any)
print(c.pop() as Any)
print(c.pop() as Any)
print(c.pop() as Any)
print(c.pop() as Any)
<代码>导入基础
C类:NSObject{
私有枚举关联的ObjectKey{
静态变量队列:Int8=0
}
私有变量队列:数组{
得到{
guard let existingValue=objc_getAssociatedObject(self,&AssociatedObjectKeys.queue)else{
self.queue=[]
返回[]
}
guard let existingArray=existingValue as?Array else{
fatalError(“找到关联的