Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 何时使用一次分派与重新分配?(可可/椰子酱)_Objective C_Cocoa_Cocoa Touch - Fatal编程技术网

Objective c 何时使用一次分派与重新分配?(可可/椰子酱)

Objective c 何时使用一次分派与重新分配?(可可/椰子酱),objective-c,cocoa,cocoa-touch,Objective C,Cocoa,Cocoa Touch,我经常使用简单的非编译时不可变对象:如数组@[@“a”,“@“b”]或字典@{@“a”:@“b”} 我一直在努力重新分配它们: - (void)doSomeStuff { NSArray<NSString *> *fileTypes = @[@"h", @"m"]; // use fileTypes } -(无效)doSomeStuff{ NSArray*文件类型=@[@“h”,@“m”]; //使用文件类型 } 并分配一次: - (void)doSomeStuf

我经常使用简单的非编译时不可变对象:如数组
@[@“a”,“@“b”]
或字典
@{@“a”:@“b”}

我一直在努力重新分配它们:

- (void)doSomeStuff {
    NSArray<NSString *> *fileTypes = @[@"h", @"m"];
    // use fileTypes
}
-(无效)doSomeStuff{
NSArray*文件类型=@[@“h”,@“m”];
//使用文件类型
}
并分配一次:

- (void)doSomeStuff {
    static NSArray<NSString *> * fileTypes;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        fileTypes = @[@"h", @"m"];
    });
    // use fileTypes
}
-(无效)doSomeStuff{
静态NSArray*文件类型;
静态调度一次;
一次发送(一次发送)^{
文件类型=@[@“h”,@“m”];
});
//使用文件类型
}
是否有关于何时使用每个构造的建议?比如:

  • 取决于分配对象的大小
  • 取决于分配的频率
  • 取决于设备(iPhone 4与iMac 2016)

我该怎么想呢?

你的项目清单是一个好的开始。记忆是另一个考虑因素。
静态
变量将从实际初始化时起一直保留在内存中,直到应用程序终止。显然,局部变量将在方法末尾被释放(假设没有进一步的引用)

可读性也是一个值得考虑的问题。重新分配行比
dispatch\u once
设置更容易阅读

对于一个小数组,我会重新分配作为第一选择。头顶很小。除非在紧密循环中创建阵列,否则性能可以忽略不计

我会使用
dispatch\u once
static
变量来处理需要更多开销的事情,比如创建日期格式化程序。但是,用户更改设备的区域设置时会产生反应开销

最后,我的思考过程是首先使用重新分配。然后,考虑使用<代码>静态< /代码>和<代码> DeXCHLYON/<代码>是否有明显的好处。如果没有值得使用
静态
的理由,我会将其保留为局部变量


如果重新分配的开销(速度)太大(但如果永久内存命中太大),请使用
static

第二种方法更复杂。因此,如果需要,您应该使用它,但不能将其作为默认值


通常,当创建对象的费用非常昂贵(几乎从来没有)或需要实例对象的单个标识(共享实例,有时称为singleton,这是不正确的)。在这种情况下,您将认识到您需要它。

dispatch\u once\t

这有两个主要好处:1)保证在应用程序运行的生命周期内只调用一次方法,2)可以使用该方法实现延迟初始化,如下面的手册页所述

从for
dispatch\u once()

函数的dispatch_once()提供了一种简单有效的机制,可以精确地运行初始化程序一次,类似于pthread_once(3)。设计良好的代码隐藏了惰性初始化的使用

一次调度的一些用例

  • 独生子女
  • 初始化文件系统资源,如文件句柄
  • 由一组实例共享并占用大量内存的任何静态变量
  • 静态,不发送一次

    静态声明的变量未包装在
    dispatch\u once
    块中,它仍然有被许多实例共享的好处。例如,如果有一个名为
    defaultColor
    的静态变量,则对象的所有实例都会看到相同的值。因此,它是特定于类的,而不是特定于实例的

    但是,当您需要保证只调用一次块时,您需要使用
    dispatch\u once\u t

    不变性

    你还提到了不变性。不变性与只运行一次无关——因此静态不可变变量和实例不可变变量都存在这种情况。例如,有时可能需要初始化不可变对象,但每个实例的不可变对象仍然可能不同(在其值取决于其他实例变量的情况下)。在这种情况下,不可变对象不是静态的,仍然可以使用来自多个实例的不同值进行初始化。在这种情况下,属性是从其他实例变量派生的,因此不允许在外部进行更改

    关于不变性与易变性的说明,摘自:

    考虑一个场景,其中所有对象都可能发生变异。在您的应用程序中,您调用一个方法并返回对表示字符串的对象的引用。您可以在用户界面中使用此字符串来标识特定的数据段。现在,应用程序中的另一个子系统获得了它自己对该字符串的引用,并决定对其进行修改。突然间,你的标签从你下面变了。例如,如果您得到一个用于填充表视图的数组的引用,情况可能会变得更加糟糕。用户选择与数组中某个对象对应的行,该对象已被程序中其他地方的某些代码删除,问题随之出现。不变性是一种保证,在您使用对象时,对象的值不会意外变化

    很好的不变性候选对象是封装离散值集合或包含存储在缓冲区中的值(缓冲区本身是字符或字节的集合类型)的对象。但并非所有这样的值对象都能从可变版本中获益。包含单个简单值的对象,例如NSNumber或NSDate的实例,不适合用于可变性。在这些情况下,当表示的值发生变化时,用新实例替换旧实例更有意义

    有关性能的说明,请参阅:

    表演家