最近我使用数组工作很多,我很想知道......这两行之间有什么区别。
NSArray *array = [NSArray arrayWithArray:someArray];
和
NSArray *array = [someArray copy];
哪个更快?如果我们有NSMutableArray
和mutableCopy
,该怎么办?
答案 0 :(得分:24)
不要担心。过早优化。哪个更快?
主要区别:第一种方法导致自动释放"复制"当你拥有在第二行创建的对象时,你不会拥有并且不必释放。 顺便说一下,这两个数组都是不可变的。
答案 1 :(得分:21)
除了其他答案,还要注意,当someArray
为零时,
第一行将array
指向一个空数组,第二行将指向空数组
它指向零。这可能是一个重要的区别,尤其是在可变数组中。
答案 2 :(得分:7)
两者之间的区别在于后者将被保留。前者将被自动释放。
两个版本都是数组的浅表副本。
NSMutableArray *notMutableReally = [NSArray arrayWithArray:aMutableArray];
在您尝试将NSArray
分配给NSMutableArray
时,应该给您一个编译器警告。
使用。
NSMutableArray *mutableArrayCopy = [NSMutableArray arrayWithArray:aMutableArray];
哪个更快?别担心,它们都比你将要做的其他东西快得多。如果你真的在乎,请查看仪器。
答案 3 :(得分:4)
主要区别在于-copy
更了解如何复制自身(可以更有效地执行它并且可能使用更适应的NSArray子类),而+arrayWithArray:
将创建{{1}的新实例(实际上,Foundation用于数组的具体类)并使用相同的初始对象列表来提供它。它还会添加一个额外的自动释放。
所以NSArray
(非常非常)可能更有效率。
事实上,对于不可变的-copy
,NSArrays
正在执行-copy
,所以它甚至不打扰创建新实例。
答案 4 :(得分:3)
NSMutableArray *arr = [NSMutableArray array];
for ( int i = 0; i < 10000; i ++)
{
[arr addObject:@(i*1000000ULL)];
}
// MARK
// arr = (id)[NSArray arrayWithArray:arr];
NSTimeInterval t = [NSDate timeIntervalSinceReferenceDate];
NSArray *res = nil;
for ( int i = 0; i < 10000; i ++)
{
res = [arr copy];
}
NSLog(@"time A: %f", [NSDate timeIntervalSinceReferenceDate] - t);
t = [NSDate timeIntervalSinceReferenceDate];
for ( int i = 0; i < 10000; i ++)
{
res = [NSArray arrayWithArray:arr];
}
NSLog(@"time B: %f", [NSDate timeIntervalSinceReferenceDate] - t);
时间A:1.572795,时间B:1.539150,B [NSArray arrayWithArray:]总是更快,但时差非常小。 但如果我们取消注释&#34; MARK&#34;从NSArray获取副本而不是NSMutableArray我们将有其他运行时A:0.000473时间B:1.548400结果:〜3200倍快
答案 5 :(得分:1)
其中一个可能更快。运行它们一百万次,看看是否有人获胜。
如果NSArray
vs NSMutableArray
,则复制的不可变数组不必实际返回副本,因为它不能更改。但是,如果您有一个可变数组,则需要复制它,因为您可以更改原始数组。当然,做一个可变副本总是需要返回一个新对象。
在整个应用程序中,速度和内存差异可能与其他所有内容相比并不重要。
答案 6 :(得分:1)
在斯威夫特,它非常不同。感谢新的开源Swift基金会,我们知道虽然init(array:)
创建了一个包含给定项目的新数组(如果有的话),但copy()
只返回self
。
public override func copy() -> AnyObject {
return copyWithZone(nil)
}
public func copyWithZone(zone: NSZone) -> AnyObject {
return self
}
https://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/NSArray.swift#L82
public convenience init(array: [AnyObject]) {
self.init(array: array, copyItems: false)
}
public convenience init(array: [AnyObject], copyItems: Bool) {
let optionalArray : [AnyObject?] =
copyItems ?
array.map { return Optional<AnyObject>(($0 as! NSObject).copy()) } :
array.map { return Optional<AnyObject>($0) }
// This would have been nice, but "initializer delegation cannot be nested in another expression"
// optionalArray.withUnsafeBufferPointer { ptr in
// self.init(objects: ptr.baseAddress, count: array.count)
// }
let cnt = array.count
let buffer = UnsafeMutablePointer<AnyObject?>.alloc(cnt)
buffer.initializeFrom(optionalArray)
self.init(objects: buffer, count: cnt)
buffer.destroy(cnt)
buffer.dealloc(cnt)
}
https://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/NSArray.swift#L116
所以,显然,copy()
更快,现在你知道它们是如何工作的! (仅限于Swift)