Swift 计算属性不能在 init 中使用?

2023-12-07

我正在尝试将 MultipeerConnectivity 框架与 Swift 一起使用。我有以下属性:

var peerId: MCPeerID?;
let advertiser: MCNearbyServiceAdvertiser;
let browser: MCNearbyServiceBrowser;
var session: MCSession? 
 ....

在我的 init 方法中,我初始化所有存储的属性,如下所示:

  init() {
    let defaults = NSUserDefaults.standardUserDefaults();
    let dataToShow = defaults.dataForKey("kPeerID");
        peerId = NSKeyedUnarchiver.unarchiveObjectWithData(dataToShow) as? MCPeerID;
    if !peerId {
        peerId = MCPeerID(displayName: UIDevice.currentDevice().name);
        let data: NSData = NSKeyedArchiver.archivedDataWithRootObject(peerId);
        defaults.setObject(data, forKey: "kPeerID");
        defaults.synchronize();
    }

    advertiser = MCNearbyServiceAdvertiser(peer: peerId, discoveryInfo:nil, serviceType: "stc-classroom");
    browser = MCNearbyServiceBrowser(peer: peerId, serviceType: "stc-classroom");
    session = MCSession(peer: self.peerId);
    super.init();

    session!.delegate = self;
    advertiser.delegate = self;
    browser.delegate = self;
}

现在,正如您所看到的,有相当多的代码行可以为peerId赋值(Apple推荐的方式),所以我认为最好将该逻辑放入计算属性中,因此我用计算属性替换了peerId存储属性,并且初始化方法如下:

 var peerId: MCPeerID {
    let defaults = NSUserDefaults.standardUserDefaults();
    let dataToShow = defaults.dataForKey("kPeerID");
    var peer = NSKeyedUnarchiver.unarchiveObjectWithData(dataToShow) as? MCPeerID;
    if peer == nil {
        peer = MCPeerID(displayName: UIDevice.currentDevice().name);
        let data: NSData = NSKeyedArchiver.archivedDataWithRootObject(peer);
        defaults.setObject(data, forKey: "kPeerID");
        defaults.synchronize();
    }
    return peer!;
}

现在我的 init 方法更加干净和简短,如下所示:

init() {
    advertiser = MCNearbyServiceAdvertiser(peer: peerId, discoveryInfo:nil, serviceType: "stc-classroom");
    browser = MCNearbyServiceBrowser(peer: peerId, serviceType: "stc-classroom");
    session = MCSession(peer: self.peerId);        
    super.init();

    session!.delegate = self;
    advertiser.delegate = self;
    browser.delegate = self;
}

但现在编译器抱怨,因为我在浏览器/广告商/会话初始化中访问peerId时尝试访问self。我知道在 Swift 中,所有属性都必须先初始化,然后才能使用它们,并且 self 被隐式调用,因此会出现错误。但显然这意味着我无法在 init 方法中调用计算属性,所以我想知道是否有更好的方法来实现我想要做的事情?我知道我可以为每个计算属性创建存储属性并将其视为 iVar,但这似乎也不是一个优雅的解决方案。

我非常感谢你对这些人的帮助。


Swift 书没有直接讨论初始化和计算属性,但在有关继承和初始化的部分中提供了相关信息:

两阶段初始化
Swift 中的类初始化是一个两阶段的过程。在第一阶段,每个存储的属性是 由引入它的类分配一个初始值。一旦 每个存储属性的初始状态已经确定, 第二阶段开始,每个班级都有机会 在新实例之前进一步自定义其存储的属性 视为已准备好使用。

基本上,您需要为所有非可选存储属性分配一个初始值(看起来像advertiser and browser),然后您才能调用任何方法或访问任何计算属性。您可能想初始化peerId有一个闭包,使用这种方法:

var peerId: MCPeerID = {
    let defaults = NSUserDefaults.standardUserDefaults()
    let dataToShow = defaults.dataForKey("kPeerID")
    var peer = NSKeyedUnarchiver.unarchiveObjectWithData(dataToShow) as? MCPeerID
    if peer == nil {
        peer = MCPeerID(displayName: UIDevice.currentDevice().name)
        let data: NSData = NSKeyedArchiver.archivedDataWithRootObject(peer)
        defaults.setObject(data, forKey: "kPeerID")
        defaults.synchronize()
    }
    return peer!
}()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Swift 计算属性不能在 init 中使用? 的相关文章

随机推荐

  • Tastypie:使用 UTF-8 的 JSON 标头

    我使用 tastypie 返回资源 其字段之一是阿拉伯语 因此需要使用 UTF 8 与 Unicode 这就是我假设运行其架构的情况 word help text Unicode 字符串数据 例如 Hello World 下面是返回的jso
  • Visual Studio 的 NCB 文件位于哪里?

    我怀疑我的 Visual Studio Intellisense 已停止工作 我读到这可能是 NCB 文件损坏并需要删除的原因 我在整个计算机中搜索了 NCB 文件 但没有弹出搜索结果 我可以在哪里手动找到该文件 如果你有一个 它应该与您的
  • C# 将函数作为参数传递[重复]

    这个问题在这里已经有答案了 我用 C 编写了一个函数来进行数值微分 它看起来像这样 public double Diff double x double h 0 0000001 return Function x h Function x
  • 获取每个用户最近 3 个月的数据作为单独的列而不是行

    我有一个mysql表 bf monthly bill 其中来自另一个表 bf users 的每个用户的数据按月存储 我的 bf users 表的结构是 id display name 1 ABC 2 DEF 3 GHI 4 JKL bf m
  • 如何在单个创建视图上对订单和订单详细信息实施创建操作?

    有人想出了简单的解决方案吗 问题 给定两个具有一对多关系的模型类 我如何为它们设计一个单一的创建 如何将订单详细信息集合添加到尚未保留在数据库中的订单实体 我将使用什么视图模型 鉴于我有已完成的订单页面 主 那么我必须有一个收集订单详细信息
  • 我的 html5 游戏没有 windows azure 吗?

    在我的本地计算机上 我用 HTML5 html javascript 创建了一个游戏 它是一个 html 文件 位于我的桌面上 在 Chrome 中运行并在记事本中编辑 我想要做的是连接到 Azure 因为我想在游戏中存储玩家得分 正如我提
  • 有没有办法阻止 Scala 2.12 破坏 Jackson 对象映射器?

    我正在将 Scala 版本从 2 11 升级到 2 12 对象映射器似乎损坏了 我的代码的其他部分需要仅在 2 12 下可用的功能 This 使用 scala 2 12 和 Spark 2 1提到重建杰克逊是一个可能的解决方案 这真的有必要
  • 我可以通过浏览器和 JavaScript 以编程方式访问智能手机的传感器吗?

    我是否可以通过浏览器网页和 JavaScript 以编程方式访问智能手机的传感器 例如 Android 或 iPhone 设备上的加速度计 指南针等 我知道 W3C 设备标准可以允许访问相机 HTML5 很可能包含传感器 API 在完全标准
  • React Router Dom,仅显示某些页面的标题组件[重复]

    这个问题在这里已经有答案了 Header将出现在除ConfirmEmail 基本上 我不想要Header当出现ConfirmEmail组件被打开 我应该怎么办 路由器设置 import React from react import Bro
  • 没有。在 SQL Server 2005 中运行选择查询后受影响的行数

    以下是我的查询 select monNameStr as MName IsNull count c AssignmentID 0 IsNull sum s ACV 0 IsNull sum s GrossReturn 0 IsNull su
  • 在多个数据库上安装存储过程

    有什么方法可以轻松地在多个 MySQL 数据库上同时创建存储过程吗 所有数据库都安装在同一个 MySQL 上 在所有模式中安装 要获取模式列表 请使用show databases 将此与 use use schemaA use schema
  • 始终在 console.log 中显示 html 元素 (Chromium)

    我有一个 js 脚本console log有时会打印 html 元素 Chrome 有两种打印此类 DOM 元素的模式 在 html 样式中 例如 div class abc div 其中悬停会突出显示页面中的元素 然后单击会打开 DOM
  • iPhone 5 + iOS6 如何决定应用程序是否必须在信箱模式下运行

    iOS6 如何决定应用程序是否必须在 iPhone 5 上以信箱 兼容模式运行 这是构建设置参数 如 目标设备系列 吗 或者所有基于最新 SDK 构建的应用程序都必须支持 iPhone 5 屏幕尺寸 或者应用程序将以信箱模式运行 是否没有
  • 如何在 makefile 中使用 LDFLAGS

    我是 Linux 操作系统的新手 我正在尝试编译一个 c使用 makefile 文件 必须链接数学库 我的 makefile 如下所示 CC gcc CFLAGS Wall lm all client PHONY clean clean r
  • 如何连接两个不同形状的张量

    我有两个张量 get shape 400 和 1176 我想将它们连接成一个大小为 1576 的张量 我尝试了 concat 但它要求两者具有相同的维度 怎么办呢 希望您通过批量大小传递相同维度的输入 import tensorflow a
  • 指针前一变量

    据我所知 在 C 中检查指针是否是数组末尾的一个元素是完全合法的 如下所示 char arr 16 for char ptr arr ptr arr sizeof arr sizeof arr 0 ptr some code 我的问题是这样
  • MSbuild 任务失败,因为“任何 CPU”解决方案的构建顺序不正确

    我在 Teambuild 中构建两种解决方案 一种是应用程序本身 另一种是 WiX 安装程序 我想使用 任何 CPU 构建配置来构建应用程序 并使用 x86 来构建安装程序 我在项目文件中首先列出了 任何 CPU 解决方案 但 Teambu
  • pandas 按两列值过滤行,不区分大小写

    我有一个简单的数据框 如下所示 Last Known Date ConfigredValue ReferenceValue 0 24 Jun 17 False FALSE 1 25 Jun 17 FALSE FALSE 2 26 Jun 1
  • 正则表达式 WORD 的最后一个字符

    我正在尝试匹配单词中的最后一个字符 WORD 是非空白字符的序列 n r t f 或匹配 的空行 我为此所做的表达是 n t r f n t r f 正则表达式匹配空白字符或行尾后面的非空白字符 但我不知道如何阻止它从结果中排除以下空白字符
  • Swift 计算属性不能在 init 中使用?

    我正在尝试将 MultipeerConnectivity 框架与 Swift 一起使用 我有以下属性 var peerId MCPeerID let advertiser MCNearbyServiceAdvertiser let brow