加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

swift – 错误:尝试将堆栈放在不可读的内存中:

发布时间:2020-12-14 05:01:02 所属栏目:百科 来源:网络整理
导读:我正在尝试向UIViewController添加其他属性. 码: protocol AdditionalStoredProperties { associatedtype Title func getAssociatedObjectTitle(key: UnsafePointerTitle,defValue : Title)-Title }extension AdditionalStoredProperties{ func getAssociat
我正在尝试向UIViewController添加其他属性.

码:

protocol AdditionalStoredProperties
   {
        associatedtype Title
        func getAssociatedObject<Title>(key: UnsafePointer<Title>,defValue : Title)->Title
    }

extension AdditionalStoredProperties
{
    func getAssociatedObject<Title>( key: UnsafePointer<Title>,defValue : Title)->Title
    {
        guard let actual_value = objc_getAssociatedObject(self as! AnyObject,key) as? Title else
        {
            return defValue
        }
        return actual_value
    }

 }

extension UIViewController:AdditionalStoredProperties
{
    typealias Title = String
    var previousPage : String
     {
        get { return getAssociatedObject(&self.previousPage,defValue: self.previousPage) }
        set { objc_setAssociatedObject(self,&self.previousPage,newValue,.OBJC_ASSOCIATION_RETAIN)}
    }
}

但是我收到以下错误:

错误:尝试将堆栈放在不可读的内存中:

我知道我们不能直接将存储的属性添加到扩展,所以我尝试使用objc_setAssociatedObject()添加它

解决方法

你正在做的事情有很多问题:

>尝试在自己的getter中访问self.previousPage将递归调用自身.
>您不能将& self.previousPage用作稳定或唯一的指针值,因为它将是指向临时变量的指针(因为您正在处理计算属性).因此,您不能将其用作关联对象的键. Swift仅为静态和全局存储变量保证稳定且唯一的指针值(有关详细信息,请参阅this Q&A).
>您应该使AdditionalStoredProperties成为一个类绑定协议(带有:class),因为您只能将关联对象添加到Objective-C类(在Apple平台上,Swift类是基于它构建的).虽然你可以将一个结构桥接到AnyObject(它将被封装在一个不透明的Obj-C兼容包装器中),但它只是那个;一座桥.无法保证您将获得相同的实例,因此无法保证关联的对象将保持不变.
>您可能并不认为Title是您协议的关联类型;你没有用它做任何事情(getAssociatedObject(key:defValue :)定义的通用占位符Title完全不相关).

记住这些要点,这是您的代码的固定版本:

protocol AdditionalStoredProperties : class {
    func getAssociatedObject<T>(ofType: T.Type,key: UnsafeRawPointer,defaultValue: @autoclosure () -> T) -> T
}

extension AdditionalStoredProperties {

    func getAssociatedObject<T>(ofType: T.Type,defaultValue: @autoclosure () -> T) -> T {

        // or: return objc_getAssociatedObject(self,key) as? T ?? defaultValue()
        guard let actualValue = objc_getAssociatedObject(self,key) as? T else {
            return defaultValue()
        }
        return actualValue
    }
}

extension UIViewController : AdditionalStoredProperties {

    private enum AssociatedObjectKeys {
        static var previousPage: Never?
    }

    var previousPage: String {
        get {
            // return the associated object with a default of "" (feel free to change)
            return getAssociatedObject(ofType: String.self,key: &AssociatedObjectKeys.previousPage,defaultValue: "")
        }
        set {
            objc_setAssociatedObject(self,&AssociatedObjectKeys.previousPage,.OBJC_ASSOCIATION_RETAIN)
        }
    }
}

请注意,我们是:

>使用静态存储属性以获取指针值以用作关联对象的键.再次,这是因为Swift guarantees stable and unique pointer values for static and global stored variables.>使用@autoclosure作为defaultValue:参数,因为如果已存在关联对象,则可能不需要对其进行求值.>使用key:参数获取UnsafeRawPointer,因为指针对象的类型无关紧要;它只是内存中用作密钥的位置.>使用ofType:参数明确地满足通用占位符.这主要是一个偏好问题,但我更喜欢明确地拼写这些东西,而不是依赖于类型推断.>使用camelCase而不是snake_case,就像Swift惯例一样.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读