这是一个小细节,但每次我懒得加载一些东西我都会被它抓住.这两种方法都可以接受吗?要么更好吗?假设变量具有retain属性.
方法#1
(AnObject *)theObject{
if (theObject == nil){
theObject = [[AnObject createAnAutoreleasedObject] retain];
}
return theObject;
}
Run Code Online (Sandbox Code Playgroud)
方法#2
(AnObject *)theObject{
if (theObject == nil){
self.theObject = [AnObject createAnAutoreleasedObject];
}
return theObject;
}
Run Code Online (Sandbox Code Playgroud)
首先,我不确定是否可以访问访问者中的另一个访问者功能(但不知道为什么不这样做).但似乎设置类变量而不通过setter可能同样糟糕,如果setter执行某些特殊操作(或者如果属性更改为除了retain之外的内容并且未检查getter).
memory-management lazy-loading objective-c lazy-initialization
我有一个属性为Dictionary的类:
public class Entity
{
public Dictionary<string, string> Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我想切换此属性以使用延迟初始化.我尝试了以下方法:
public class Entity
{
private Lazy<Dictionary<string, string>> name = new Lazy<Dictionary<string, string>>(() => new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase));
public Dictionary<string, string> Name
{
get
{
return name;
}
set
{
name = value;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这当然是一个错误,因为名称和名称有不同的类型.但是对于我的生活,我无法弄清楚如何正确指定.我真正想要的是让Name保持为null,直到我访问它,然后在第一次读或写时创建它.
我来自Java背景.我有以下程序.
#include <string>
#include <iostream>
class First {
public:
First(int someVal): a(someVal) {
}
int a;
};
class Second {
public:
First first;
Second() { // The other option would be to add default value as ": first(0)"
first = First(123);
}
};
int main()
{
Second second;
std::cout << "hello" << second.first.a << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
在课堂上Second,我希望变量first保持未初始化,直到我专门初始化它Second()'s constructor.有办法吗?或者我只剩下2个选项?:
我无法first在初始化列表中使用正确的值初始化,因为该值是在某些操作之后获得的.因此,实际所需的值仅first在Second()构造函数中可用.
我不想初始化视图控制器,直到需要显示其视图。
lazy var foo: NSViewController! = {
let foo = NSViewController()
foo.representedObject = self.representedObject
return foo
}()
// ...
override var representedObject: Any? {
didSet {
if foo != nil {
foo.representedObject = representedObject
}
}
}
Run Code Online (Sandbox Code Playgroud)
self.representedObject是在以前foo被引用之前设置的,但是每次调用时if foo != nil,它都会初始化foo:c
有没有什么办法,如果我可以测试foo也已经被设置?
我一直想知道应该如何处理这种异常现象:
但是,如何避免JPA LazyInitialization异常呢?DTO转换可能需要Lazy Fetched数据,但由于服务层处理了事务,因此无法进行转换.
有一些我能想到的方法,但都是丑陋的.将DTO转换放在服务层中对我来说似乎是最好的.
我想序列化和DeSerialize一个包含Lazy Collection一些自定义对象的对象.
通常情况下一切都很好,但是,如果更改了用于序列化的类的名称空间,则会出现此问题.
SerializationBinder在反序列化时,我写了一个指向正确的类.但由于某种原因,我没有得到反序列化的值.
以下代码片段解释了我遇到的问题;
用于序列化的类:
namespace ConsoleApplication14
{
[Serializable]
public class MyInnerClass : ISerializable
{
private string _stringInInnerClassKey = "StringInInnerClass";
public string StringInInnerClass { get; set; }
public MyInnerClass() { }
private MyInnerClass(SerializationInfo info, StreamingContext context)
{
StringInInnerClass = info.GetString(_stringInInnerClassKey);
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue(_stringInInnerClassKey, StringInInnerClass);
}
}
[Serializable]
public class MyOuterClass : ISerializable
{
private string _collectionOfObjKey = "CollectionOfInnerObj";
public Lazy<Collection<MyInnerClass>> CollectionOfInnerObj { get; set; }
private MyOuterClass(SerializationInfo info, StreamingContext context) …Run Code Online (Sandbox Code Playgroud) c# serialization lazy-initialization serializationbinder deserialization
我想创建一个像属性一样工作的装饰器,只调用一次装饰函数,后续调用总是返回第一次调用的结果.一个例子:
def SomeClass(object):
@LazilyInitializedProperty
def foo(self):
print "Now initializing"
return 5
>>> x = SomeClass()
>>> x.foo
Now initializing
5
>>> x.foo
5
Run Code Online (Sandbox Code Playgroud)
我的想法是为此编写一个自定义装饰器.所以我开始了,这就是我走了多远:
class LazilyInitializedProperty(object):
def __init__(self, function):
self._function = function
def __set__(self, obj, value):
raise AttributeError("This property is read-only")
def __get__(self, obj, type):
# problem: where to store the value once we have calculated it?
Run Code Online (Sandbox Code Playgroud)
如您所见,我不知道存储缓存值的位置.最简单的解决方案似乎只是维护字典,但我想知道是否有更优雅的解决方案.
编辑很抱歉,我忘了提到我希望该房产是只读的.
我通常懒惰地在他们的getter方法中实例化我的@property对象,如下所示:
@interface MyGenericClass : UIViewController
@property(nonatomic, readonly) UIImageView *infoImageView
// ...
@implementation GenericClass
- (UIImageView *)infoImageView
{
if (!_infoImageView) {
_infoImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"PlaceholderInfoImage"]];
}
return _infoImageView;
}
Run Code Online (Sandbox Code Playgroud)
但是当子类化时,我经常想要覆盖一些@properties以使其更具子类.所以我想改变实例化并执行以下操作:
@interface MySpecificSubclass : MyGenericClass
//...
@implementation MySpecificSubclass
- (UIImageView *)infoImageView
{
if (!_infoImageView) {
_infoImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"SpecialInfoImage"]];
}
return _infoImageView;
}
Run Code Online (Sandbox Code Playgroud)
但那是不可能的,因为子类无法访问_infoImageView iVar.
我正在努力做坏事吗?或者有一个共同的解决方案/最佳实践吗?我看到的唯一解决方案是让iVar公开,这感觉违反了封装原则......
感觉这是一个非常基本的问题,那里必须有数百万的答案,但是在搜索了几个小时之后,我发现的一切都是Objective-C:当覆盖超类getter并尝试访问ivar时编译错误 ,但是它没有解决方案.
overriding lazy-loading properties objective-c lazy-initialization
我正在尝试在 youtube 中实现一个示例,导师做对了,但我遇到了错误。
我已经有一个私有构造函数,我的代码中不能有公共构造函数。
private static int _InstanceCount = 0;
private SingletonDemo1()
{
_InstanceCount++;
Console.WriteLine("Instance Count: " + _InstanceCount.ToString());
}
private static readonly Lazy<SingletonDemo1> _Instance = new Lazy<SingletonDemo1>();
public static SingletonDemo1 Instance
{
get
{
return _Instance.Value;
}
}
Run Code Online (Sandbox Code Playgroud) 我意识到Lazy使用 Dagger 完成注入的推荐方法是添加Lazy到字段注入点。例如,
class Foo {
@Inject lateinit var bar: Lazy<Bar>
fun useBar() = bar.get().doSomething()
}
Run Code Online (Sandbox Code Playgroud)
使用构造函数注入怎么样?我还没有看到有人这样做。
class Foo @Inject constructor(private val fizz: Fizz,
private val bar: Lazy<Bar>) {
fun useBar() = bar.get().doSomething()
}
Run Code Online (Sandbox Code Playgroud)
总结一下,在进行 Dagger 延迟注入时,我可以Lazy<Bar>在构造函数中使用吗?或者我唯一的选择是转移Lazy<Bar>到字段注入,同时将其他非惰性依赖项保留在通过构造函数注入的同一类中?
感谢您的指点!
c# ×3
lazy-loading ×3
objective-c ×2
properties ×2
c++ ×1
class ×1
constructor ×1
dagger ×1
dagger-2 ×1
decorator ×1
descriptor ×1
dto ×1
java ×1
jpa ×1
kotlin ×1
overriding ×1
python ×1
swift ×1
transactions ×1