ViewModel 和 Service 类的实例化

2024-04-19

我试图理解 ViewModel 和 Service 类的实例化,并将其写下来供其他人使用。请在需要的地方更正/添加。

ViewModel 和服务的实例化并不是以最常见的方式完成的。这是使用反射完成的。

在 TipCalc 中,您有:

public class FirstViewModel : MvxViewModel
{
    private readonly ICalculationService _calculationService;

    public FirstViewModel(ICalculationService calculationService)
    {
        _calculationService = calculationService;
    }
...
}

and

public class App : Cirrious.MvvmCross.ViewModels.MvxApplication
{
    public override void Initialize()
    {
        CreatableTypes()
         .EndingWith("Service")
         .AsInterfaces()
         .RegisterAsLazySingleton();
    ...
    }
}

在Initialize()期间,设计为Service(名称以Service结尾)的接口和类使用反射以及接口名称和类名称(IPersonService和PersonService)进行配对。这稍后用于反向查找该类的实例(查找表包含对服务类的单例实例的惰性引用。当为 null 时,将创建服务。

public FirstViewModel(ICalculationService CalculationService) 引用 CalculationService 的实例。这是通过使用之前创建的查找表来完成的。

ViewModel 的实例化是通过 Mvx 框架完成的。当 MvxFramework 被“要求”实例化 ViewModel 时,它将反映 ViewModel 并确定该类上有哪些构造函数。如果有无参数构造函数,那么将使用它。如果存在带有参数的构造函数,并且该参数是服务类的接口,则该服务的(单例)实例将用作参数。

服务以类似的方式实例化;它们的构造函数被反射,参数被实例化(单例)。等等。


这里使用的想法是:

  • 服务定位器模式
  • 控制反转

有很多关于这方面的文章和介绍 - 一些很好的起点是马丁·福勒简介 http://www.martinfowler.com/articles/injection.html and Joel Abrahamsson 的 IoC 介绍 http://joelabrahamsson.com/inversion-of-control-an-introduction-with-examples-in-net/。我也做了一些动画幻灯片 https://github.com/slodge/MvvmCross-Presentations/blob/master/MvxDay/InterfaceDrivenDevelopment.pptx作为一个简单的演示。


特别是在 MvvmCross 中,我们提供了一个静态类Mvx它充当注册和解析接口及其实现的单一位置。

服务地点-登记与解决

MvvmCross Service Location 的核心思想是您可以编写如下类和接口:

public interface IFoo
{
    string Request();
}

public class Foo : IFoo
{
    public string Request()
    {
        return "Hello World";
    }
}

单例注册

写完这对后,您就可以注册一个Foo实例作为单例实现IFoo using:

// every time someone needs an IFoo they will get the same one
Mvx.RegisterSingleton<IFoo>(new Foo());

如果你这样做了,那么任何代码都可以调用:

    var foo = Mvx.Resolve<IFoo>();

每个调用都会返回同一个实例 of Foo.

惰性单例注册

作为此方法的变体,您可以注册一个惰性单例。这是写的

// every time someone needs an IFoo they will get the same one
// but we don't create it until someone asks for it
Mvx.RegisterSingleton<IFoo>(() => new Foo());

在这种情况下:

  • no Foo最初被创建
  • 第一次调用任何代码Mvx.Resolve<IFoo>()然后是一个新的Foo将被创建并返回
  • 所有后续调用都将获得第一次创建的相同实例

“动态”注册

最后一个选择是您可以注册IFoo and Foo配对为:

// every time someone needs an IFoo they will get a new one
Mvx.RegisterType<IFoo, Foo>();

在这种情况下,每次调用Mvx.Resolve<IFoo>()将创建一个新的Foo- 每次调用都会返回不同的Foo.

最后登记的获胜者

如果您创建一个接口的多个实现并将它们全部注册:

Mvx.RegisterType<IFoo, Foo1>();
Mvx.RegisterSingleton<IFoo>(new Foo2());
Mvx.RegisterType<IFoo, Foo3>();

然后每次调用replaces之前的注册 - 所以当客户打电话时Mvx.Resolve<IFoo>()然后将返回最近的注册信息。

这对于以下方面很有用:

  • 覆盖默认实现
  • 根据应用程序状态替换实现 - 例如用户通过身份验证后,您可以替换空的IUserInfo与真实的实施。

按惯例批量注册

MvvmCross 的默认 NuGet 模板在核心中包含一个代码块App.cs like:

CreatableTypes()
    .EndingWith("Service")
    .AsInterfaces()
    .RegisterAsLazySingleton();

此代码使用反射来:

  • find all classes in the Core assembly
    • which are creatable - i.e.:
      • 有一个公共构造函数
      • are not abstract
    • 名称以 Service 结尾
  • 找到他们的接口
  • 根据它们支持的接口将它们注册为惰性单例

技术说明:这里的惰性单例实现非常技术性 - 它确保如果一个类实现IOne and ITwo那么在解析两者时将返回相同的实例IOne and ITwo.

名字的选择到此结束——Service- 选择使用惰性单例只是个人约定。如果您喜欢为对象使用其他名称或其他生命周期,您可以将此代码替换为不同的调用或多个调用,例如:

CreatableTypes()
    .EndingWith("SingleFeed")
    .AsInterfaces()
    .RegisterAsLazySingleton();
CreatableTypes()
    .EndingWith("Generator")
    .AsInterfaces()
    .RegisterAsDynamic();
CreatableTypes()
    .EndingWith("QuickSand")
    .AsInterfaces()
    .RegisterAsSingleton();

在那里您还可以使用额外的Linq如果您愿意,可以帮助进一步定义您的注册的辅助方法 - 例如Inherits, Except. WithAttribute, Containing, InNamespace...例如

        CreatableTypes()
            .StartingWith("JDI")
            .InNamespace("MyApp.Core.HyperSpace")
            .WithAttribute(typeof(MySpecialAttribute))
            .AsInterfaces()
            .RegisterAsSingleton();

当然,您也可以在 Core 以外的程序集上使用相同类型的注册逻辑 - 例如:

typeof(Reusable.Helpers.MyHelper).Assembly.CreatableTypes()
    .EndingWith("Helper")
    .AsInterfaces()
    .RegisterAsDynamic();

或者,如果您不想使用这种基于反射的注册,那么您可以手动注册您的实现:

Mvx.RegisterSingleton<IMixer>(new MyMixer());
Mvx.RegisterSingleton<ICheese>(new MyCheese());
Mvx.RegisterType<IBeer, Beer>();
Mvx.RegisterType<IWine, Wine>();

选择是yours.

构造函数注入

Mvx.Resolve<T>, the Mvx静态类提供了基于反射的机制来在对象构造期间自动解析参数。

例如,如果我们添加一个类:

public class Bar
{
    public Bar(IFoo foo)
    {
        // do stuff
    }
}

然后你可以使用以下方法创建这个对象:

    Mvx.IocConstruct<Bar>();

这次通话期间发生的事情是:

  • MvvmCross:
    • 使用Reflection来查找构造函数Bar
    • 查看该构造函数的参数,发现它需要一个IFoo
    • uses Mvx.Resolve<IFoo>()获取已注册的实现IFoo
    • 使用反射来调用构造函数IFoo范围

构造函数注入和 ViewModel

创建 ViewModel 时,这种“构造函数注入”机制在 MvvmCross 内部使用。

如果您声明一个 ViewModel,如下所示:

 public class MyViewModel : MvxViewModel
 {
     public MyViewModel(IMvxJsonConverter jsonConverter, IMvxGeoLocationWatcher locationWatcher)
     {
        // ....
     }
 }

那么 MvvmCross 将使用Mvx用于解析对象的静态类jsonConverter and locationWatcher when a MyViewModel被建造。

这个很重要因为:

  1. 它可以让您轻松提供不同的locationWatcher不同平台上的类(在 iPhone 上,您可以使用与CoreLocation,在 Windows Phone 上,您可以使用与以下对象对话的观察者System.Device.Location
  2. 它允许您轻松地在单元测试中提供模拟实现
  3. 它允许您覆盖默认实现 - 如果您不喜欢Json.NetJson 的实现,您可以使用ServiceStack.Text而是实施。

构造函数注入和链接

在内部,Mvx.Resolve<T>当需要新对象时,机制使用构造函数注入。

这使您能够注册依赖于其他接口的实现,例如:

public interface ITaxCalculator
{
    double TaxDueFor(int customerId)
}

public class TaxCalculator
{
    public TaxCalculator(ICustomerRepository customerRepository, IForeignExchange foreignExchange, ITaxRuleList taxRuleList)
    {
    // code...
    }

    // code...
}

如果您随后将此计算器注册为:

Mvx.RegisterType<ITaxCalculator, TaxCalculator>();

然后当客户打电话时Mvx.Resolve<ITaxCalculator>()然后 MvvmCross 将创建一个新的TaxCalculator实例,解决所有ICustomerRepository, IForeignExchange and ITaxRuleList在操作过程中。

进一步地,这个过程是递归的- 所以如果这些返回的对象中的任何一个需要另一个对象 - 例如如果你的IForeignExchange实施需要一个IChargeCommission对象 - 那么 MvvmCross 也会为您提供 Resolve。

当我需要在不同平台上实现不同的实现时,如何使用 IoC?

有时您需要在 ViewModel 中使用某些特定于平台的功能。例如,您可能想要获取 ViewModel 中的当前屏幕尺寸 - 但没有现有的可移植 .Net 调用来执行此操作。

当您想要包含这样的功能时,有两个主要选择:

  1. 在核心库中声明一个接口,然后在每个 UI 项目中提供并注册一个实现。
  2. 使用或创建一个plugin

1. PCL 接口与特定于平台的实现

在您的核心项目中,您可以声明一个接口,并且可以在您的类中使用该接口 - 例如:

public interface IScreenSize
{
    double Height { get; }
    double Width { get; }
}

public class MyViewModel : MvxViewModel
{
    private readonly IScreenSize _screenSize;

    public MyViewModel(IScreenSize screenSize)
    {
         _screenSize = screenSize;
    }

    public double Ratio
    {
        get { return (_screenSize.Width / _screenSize.Height); }
    }
}

在每个 UI 项目中,您可以声明特定于平台的实现IScreenSize。一个简单的例子是:

public class WindowsPhoneScreenSize : IScreenSize
{
    public double Height { get { return 800.0; } }
    public double Width { get { return 480.0; } }
}

然后,您可以在每个特定于平台的安装文件中注册这些实现 - 例如你可以覆盖MvxSetup.InitializeFirstChance with

protected override void InitializeFirstChance()
{
    Mvx.RegisterSingleton<IScreenSize>(new WindowsPhoneScreenSize());
    base.InitializeFirstChance();
}

完成此操作后,然后MyViewModel将获得正确的特定于平台的实现IScreenSize在每个平台上。

2. 使用或创建plugin

A Plugin是一种 MvvmCross 模式,用于组合 PCL 程序集以及可选的一些特定于平台的程序集以打包某些功能。

这个插件层只是一个模式 - 一些简单的约定 - 用于命名相关的程序集,包括小的PluginLoader and Plugin辅助类,以及使用 IoC。通过这种模式,它允许跨平台和跨应用程序轻松地包含、重用和测试功能。

例如,现有的插件包括:

  • 一个文件插件,提供访问System.IO操作文件的类型方法
  • 一个位置插件,提供对地理位置信息的访问
  • 一个 Messenger 插件,提供对 Messenger/事件聚合器的访问
  • PictureChooser 插件,提供对相机和媒体库的访问
  • ResourceLoader 插件提供了一种访问应用程序打包在 .apk、.app 或 .ipa 中的资源文件的方法
  • 一个 SQLite 插件,提供访问SQLite-net在所有平台上。
Plugin Use

如果您想了解如何在您的应用程序中使用这些插件,那么:

  • the N+1 videos provide a good starting point - see http://mvvmcross.wordpress.com/ http://mvvmcross.wordpress.com/ - especially :
    • N=8 - 位置http://slodge.blogspot.co.uk/2013/05/n8-location-location-location-n1-days.html http://slodge.blogspot.co.uk/2013/05/n8-location-location-location-n1-days.html
    • N=9 - 信使http://slodge.blogspot.co.uk/2013/05/n9-getting-message-n1-days-of-mvvmcross.html http://slodge.blogspot.co.uk/2013/05/n9-getting-message-n1-days-of-mvvmcross.html
    • N=10 - SQLitehttp://slodge.blogspot.co.uk/2013/05/n10-sqlite-persistent-data-storage-n1.html http://slodge.blogspot.co.uk/2013/05/n10-sqlite-persistent-data-storage-n1.html
    • N=12 -> N=17 - Collect-A-Bull 应用程序http://slodge.blogspot.co.uk/2013/05/n12-collect-bull-full-app-part-1-n1.html http://slodge.blogspot.co.uk/2013/05/n12-collect-bull-full-app-part-1-n1.html
Plugin Authoring

编写插件很容易,但一开始可能会感觉有点令人畏惧。

关键步骤是:

  1. 为插件创建主 PCL 程序集 - 这应包括:

    • 您的插件将注册的接口
    • 任何共享的可移植代码(可能包括一个或多个接口的实现)
    • 一个特别的PluginLoaderMvvmCross 将使用该类来启动插件
  2. 可以选择创建特定于平台的程序集,其中:

    • 与主程序集的名称相同,但具有特定于平台的扩展名(.Droid、.WindowsPhone 等)
    • contains
      • 任何特定于平台的接口实现
      • 一个特别的PluginMvvmCross 将使用该类来启动此特定于平台的扩展
  3. 可以选择提供文档和 NuGet 打包等额外内容,这将使插件更易于重用。

我不打算在这里详细介绍如何编写插件。

如果您想了解有关编写自己的插件的更多信息,那么:

  • 有一个关于这个的演示https://speakerdeck.com/cirrious/plugins-in-mvvmcross https://speakerdeck.com/cirrious/plugins-in-mvvmcross
  • 有一个示例创建了一个Vibrate插件位于https://github.com/slodge/MvvmCross-Tutorials/tree/master/GoodVibrations https://github.com/slodge/MvvmCross-Tutorials/tree/master/GoodVibrations

如果什么...

如果...我不想使用服务位置或 IoC 怎么办

如果您不想在代码中使用它,那就不要这样做。

只需删除CreatableTypes()...来自 App.cs 的代码,然后在 ViewModel 中使用“正常代码” - 例如:

public class MyViewModel : MvxViewModel
{
    private readonly ITaxService _taxService;

    public MyViewModel()
    {
        _taxService = new TaxService();
    }
}

如果...我想使用不同的服务位置或 IoC 机制怎么办

有很多出色的现有的库包括 AutoFac、Funq、MEF、OpenNetCF、TinyIoC 等等!

如果您想替换 MvvmCross 实现,那么您需要:

  • 写某种Adapter层提供其服务位置代码作为IMvxIoCProvider
  • 覆盖CreateIocProvider在你的Setup提供这种替代方案的类IMvxIoCProvider执行。

或者,您可以组织混合情况 - 两个 IoC/ServiceLocation 系统并排存在。

如果...我想使用属性注入作为 IoC 机制怎么办

提供了 IoC 的属性注入实现示例。

可以使用以下设置覆盖来初始化:

protected override IMvxIoCProvider CreateIocProvider()
{
    return MvxPropertyInjectingIoCContainer.Initialise();
}

如果...我想要高级 IoC 功能(例如子容器)怎么办

MvvmCross 中的 IoC 容器被设计得非常轻量级,并且针对我构建的移动应用程序所需的功能级别。

如果您需要更高级/复杂的功能,那么您可能需要使用不同的提供程序或不同的方法 - 对此的一些建议将在以下内容中讨论:MvvmCross IoC 中的子容器 https://stackoverflow.com/questions/16514691/child-containers-in-mvvmcross-ioc

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ViewModel 和 Service 类的实例化 的相关文章

  • 如何在Jenkins上更改工作空间并建立记录根目录?

    我希望将 Jenkins 的数据写入驱动器 E 因为这是服务器上的大型驱动器 Jenkins 本身安装在 C 上 我怎么做 我看到的默认配置是 工作区根目录 ITEM ROOTDIR 工作区 构建记录根目录 ITEM ROOTDIR 构建
  • 在 selenium webdriver 中打开一个新窗口而不是新选项卡

    当在我的应用程序中手动单击链接时 它会在 Chrome 和 IE 中的新选项卡中打开 但是 当我的脚本运行时 该链接会在 IE 中的新窗口而不是新选项卡中打开 相同的脚本在 Chrome 中按预期运行 知道如何摆脱这个吗 更改 IE 的默认
  • 以 UTF8 而不是 UTF16 输出 DataTable XML

    我有一个 DataTable 我正在使用 WriteXML 创建一个 XML 文件 尽管我在以 UTF 16 编码导出它时遇到问题 并且似乎没有明显的方法来更改它 我了解 NET 在字符串内部使用 UTF 16 这是正确的吗 然后 我通过
  • 正则表达式 - 匹配不包含字符串的模式

    我对正则表达式很陌生 并且一直在寻找方法来做到这一点 但没有成功 给定一个字符串 我想删除以 abc 开头 以 abc 结尾且中间不包含 abc 的任何模式 如果我做 abc abc abc 它将匹配以 b 开头 以 abc 结尾并且中间包
  • Javascript/jQuery 外部高度()

    Does idOfLememt outerHeight 对所有浏览器产生相同的结果 IE7 有什么不同吗 只要去http api jquery com outerHeight http api jquery com outerHeight
  • 我如何用 javascript/jquery 进行两指拖动?

    我正在尝试创建当有两个手指放在 div 上时拖动 div 的功能 我已将 div 绑定到 touchstart 和 touchmove 事件 我只是不确定如何编写这些函数 就像是if event originalEvent targetTo
  • 服务器响应 PASV 命令返回的地址与建立 FTP 连接的地址不同

    System Net WebException 服务器响应 PASV 命令返回的地址与建立 FTP 连接的地址不同 在 System Net FtpWebRequest CheckError 在 System Net FtpWebReque
  • Maven 构建错误 TOOLS.JAR NOT FOUND IN JRE

    我在构建 Maven 项目时遇到这个问题 请帮我解决 ERROR Failed to execute goal org apache maven plugins maven compiler plugin 2 5 1 compile def
  • Android 的代码覆盖率[重复]

    这个问题在这里已经有答案了 可能的重复 Android测试代码覆盖率 Eclipse https stackoverflow com questions 3282702 android test code coverage eclipse
  • 关闭扫描仪是否会影响性能

    我正在解决一个竞争问题 在问题中 我正在使用扫描仪获取用户输入 这是 2 个代码段 一个关闭扫描器 一个不关闭扫描器 关闭扫描仪 import java util Scanner public class JImSelection publ
  • UWP 应用程序在与商店关联后崩溃

    我正在为 Windows 创建一个 cordova 应用程序 将应用程序与商店关联后 应用程序起始页变为白色空白 如果应用程序使用包标识名称 com something moretext 则该应用程序可以正常工作 但我的商店包身份名称是 5
  • 防止 Ada DLL 中的名称损坏

    有没有一种简单的方法可以防止在创建 Ada DLL 时 Ada 名称被破坏 这是我的 adb 代码 with Ada Text IO package body testDLL is procedure Print Call is begin
  • Maven2继承

    如果我有一个父 pom 并且想将其继承到多个项目 我通常通过添加到项目顶部来做到这一点
  • 文本处理问题:删除其中一列不包含特定值的行

    我有一个制表符分隔的文件 如下所示 input sequence match sequence score receptor group epitope antigen organism ASRPPGGVNEQF ASRPPGGVNEQF
  • 用 Beautiful Soup 进行抓取:为什么 get_text 方法不返回该元素的文本?

    最近我一直在用 python 开发一个项目 其中涉及抓取一些网站的一些代理 我遇到的问题是 当我尝试抓取某个知名代理站点时 当我要求 Beautiful Soup 查找 IP 在代理表中的位置时 它并没有按照我的预期执行操作 我将尝试查找每
  • RavenDB:为什么我会在此多重映射/归约索引中获得字段空值?

    受到 Ayende 文章的启发https ayende com blog 89089 ravendb multi maps reduce indexes https ayende com blog 89089 ravendb multi m
  • 如何在 Symfony 4 中为测试环境设置数据库

    我对如何在 symfony 4 中为测试环境设置数据库感到困惑 我曾经在配置测试 ymlsymfony 3 及以下版本中的文件 最佳做法是什么 我应该重新创建一个学说 yaml文件输入配置 包 测试 该文档提到如何通过编辑 phpunit
  • 将 read.csv 与符号链接文件一起使用

    我正在尝试做什么 我的源文件非常大 我想避免将其复制到其他文件夹中 我决定创建一个指向大文件的符号链接并想使用read csv读取文件 文件夹结构 项目1 数据 源文件 csv 项目2 数据 别名到源文件 csv 什么地方出了错 读取源文件
  • 如何使用 C# 以低分辨率形式提供高分辨率图像

    尝试使用 300dpi tif 图像在网络上显示 目前 当用户上传图像时 我正在动态创建缩略图 如果创建的页面引用宽度为 500x500px 的高分辨率图像 我可以使用相同的功能即时转换为 gif jpg 吗 将创建的 jpg 的即将分辨率
  • GAE 无法部署到 App Engine

    我正在尝试从 Eclipse 发布 Web 应用程序 我在 GAE 上创建了四个项目 可以通过登录我的帐户并查看控制台来查看它们 我已经改变了appengine web xml到项目的应用程序 ID 如果我将其更改为 GAE 上第一个创建的

随机推荐

  • C++ 编码指南 102

    如果您被允许在 101 条准则中添加另一个编码准 则 C 编码标准 Herb Sutter 和 Andrei Alexandrescu http www gotw ca publications c cs htm 您会添加哪一个 一年后再写
  • 模板什么时候结束?

    模板什么时候结束 我们来看看这段代码 template
  • 带有 vararg observables 的 RxJava zip

    当我们确切地知道有多少个具有确切类型的可观察量并且我们想要压缩时 我们会这样做 Observable
  • JetBrains IDE 启动时出错:应用程序无法正确启动 (0xc000007b)

    我遇到了这个错误 但在重新安装 IDE 两次后几乎找不到解决方案 甚至我安装了 多合一运行时 但这也无济于事 因为我认为问题最初是在我更改了 Windows Defender 设置中的一些设置后开始的然后尝试重置它们 但肯定其他人报告了这个
  • lambda:通过引用捕获 const 引用是否应该产生未定义的行为?

    我刚刚在代码中发现了一个令人讨厌的错误 因为我通过引用捕获了对字符串的 const 引用 当 lambda 运行时 原始字符串对象已经消失了 引用的值是空的 而目的是它包含原始字符串的值 因此出现了错误 让我困惑的是 这并没有在运行时引发崩
  • BigInteger 数字的实现和性能

    我用 C 编写了一个 BigInteger 类 它应该能够对任何大小的所有数字进行运算 目前 我正在尝试通过比较现有算法并测试它们最适合哪些位数来实现非常快速的乘法方法 但我遇到了非常意外的结果 我尝试进行 20 次 500 位数字的乘法
  • Inflector.Net 的替代品

    我想在我的项目中使用 inflector net 刚刚谷歌了一下 好像已经消失了 http andrewpeters net inflectornet http andrewpeters net inflectornet 还有其他选择吗 编
  • Chrome 开发工具中的 __puppeteer_evaluation_script__ 为空

    Puppeteer 版本 9 0 0 将调试器放入 JavaScript 代码并启动 puppeteer 时 chrome 开发工具中的源代码为空 使用 Node 运行脚本 scripts test echo Error no test s
  • Docker 和 Python virtualenv 有什么区别?

    根据我对Docker的理解 它是一个用于虚拟环境的工具 用他们的行话来说 这称为 容器化 这或多或少就是 Python 的 virtualenv 所做的事情 但是 您可以使用 virtualenvin码头工人 那么 它是虚拟环境中的虚拟环境
  • 如何监控 Tomcat 服务器上的多个 Web 应用程序(使用 JMX)?

    有没有办法监控单个 Web 应用程序的 CPU 和内存消耗Tomcat server I have Tomcat打开其 JVM 下的所有 Web 应用程序 因此我只能看到一个 JVM 无法单独监控每个 Web 应用程序 Web 应用程序是密
  • jquery中删除多个元素

    在我当前的代码中我有这样的 foo remove bar remove 有没有办法通过使用删除多个元素remove once 它不限于 remove 但只需用逗号分隔选择器 foo bar remove 多重选择器 选择器1 选择器2 选择
  • 如何调整 UIImageView 的大小以适应底层图像而不移动它?

    我有一个 UIImageView 其框架在加载图像之前设置 对于图像来说总是太大 因此 例如 当我尝试圆角时 什么也没有发生 如何调整框架大小 使其与底层图像的大小相同 同时确保 UIImageView 的中心点不会改变 如果更改 UIVi
  • CPython的静态对象地址和碎片

    I read 对于Python来说 if x 是存储x的内存地址 这是给定的id对象的属性永远不会改变 这意味着对象在其生命周期中始终存储在给定的内存地址中 这就引出了一个问题 虚拟 内存碎片怎么样 说一个物体A位于地址 1 有id1 占用
  • IIS7的工作进程是什么?

    我正在尝试在 Visual Studio 2008 中执行 附加到进程 进行调试 但我无法弄清楚要附加到哪个进程 帮助 事实上它仍然是 w3wp exe 您需要检查 显示所有会话中的进程 让它显示的选项 这也让我困惑了一段时间
  • 如果不调用notify(),等待线程会发生什么?

    如果不调用notify 等待线程会发生什么 这是虚假唤醒吗 If a waiting Thread is not notified通过致电notify or notifyAll 在所述线程正在等待的对象上 则可能会发生以下任一情况 the
  • Chrome 调试协议:HeapProfiler.getHeapSnapshot 忽略回调

    我正在开发一个测试套件 作为 Chrome 扩展实现 该套件使用 Chrome Chromium 的远程调试协议以编程方式获取和分析堆快照 因为Profiler 似乎不是公共协议的一部分 我正在使用这一页 http trac webkit
  • HTML 多选框

    我只是想知道下面的表格的名称是什么 我从早上就在谷歌上搜索 HTML 表单列表 但我在任何地方都找不到这种表单 谁能告诉我这个表单的确切名称以及它是否可以在 HTML 表单中使用 我只想在我的网站中添加这种形式 它适用于 HTML 还是我应
  • 将变量传递给 Google Cloud Functions

    我刚刚在 Beta Python 3 7 运行时中使用 HTTP 触发器编写了 Google Cloud Function 现在我试图弄清楚如何在调用函数时将字符串变量传递给函数 我已阅读文档 但没有找到任何相关内容 我的触发器类似于 ht
  • 如何在光线平行且不使用光线模式的情况下运行函数?

    After sudo pip3 install ray 我创建了一个函数foo 在射线装饰器中定义 import ray ray init ray remote def foo x print x 我希望能够使用foo并行和常规模式 忽略装
  • ViewModel 和 Service 类的实例化

    我试图理解 ViewModel 和 Service 类的实例化 并将其写下来供其他人使用 请在需要的地方更正 添加 ViewModel 和服务的实例化并不是以最常见的方式完成的 这是使用反射完成的 在 TipCalc 中 您有 public