I would like to use an array of pointers to instances of objects, but only want to create instances of those objects when required (i.e. lazily). The array corresponds to a table in the UI, so each array index corresponds to a table row.
我希望使用指向对象实例的指针数组,但只希望在需要时创建这些对象的实例(即惰性)。数组对应于UI中的一个表,因此每个数组索引对应于一个表行。
I would like to use an NSMutableArray to hold pointers to the object instances as they are created (which occurs when the user selects the corresponding row in the UI).
我希望使用NSMutableArray在创建对象实例时保存指向它们的指针(当用户选择UI中的对应行时发生)。
If a row in the table is selected, the corresponding array entry is checked. If the pointer value is nil, the instance hasn't yet been created, and so it is created at that point, and the object pointer is stored in the corresponding indexed array entry.
如果选择表中的一行,则检查相应的数组条目。如果指针值为nil,则还没有创建实例,因此在此时创建实例,对象指针存储在相应的索引数组条目中。
Obviously, this requires that I initially start with an array of nil pointers, but objC won't let me put a nil pointer in an NSArray.
显然,这要求我首先从一个空指针数组开始,但是objC不允许我在NSArray中放一个空指针。
I can't just add objects to the array as they are created, as the array index would not correspond to the table row.
我不能在创建对象时将对象添加到数组中,因为数组索引与表行不一致。
What's the best objC solution here?
这里最好的objC解决方案是什么?
3 个解决方案
#1
7
The idiomatic solution in Objective C is to use NSNull
:
Objective C中的惯用方法是使用NSNull:
The NSNull class defines a singleton object used to represent null values in collection objects (which don’t allow nil values).
NSNull类定义一个单例对象,用于表示集合对象中的空值(不允许使用nil值)。
Create your NSMutableArray
, and fill it up with [NSNull null]
objects:
创建NSMutableArray,并用[NSNull null]对象填充:
NSMutableArray *array = [NSMutableArray arrayWithCapacity:N];
for (int i = 0 ; i != 10 ; [a addObject:[NSNull null]], i++);
When you check for the presence or absence of an object in your NSMutableArray
, compare the object at index to [NSNull null]
: if they are the same, replace with a real object; otherwise, the real object is already there.
当您检查NSMutableArray中是否存在对象时,将索引处的对象与[NSNull null]进行比较:如果它们是相同的,则用一个真实的对象替换;否则,真正的对象已经在那里了。
if ([array objectAtIndex:index] == [NSNull null]) {
MyRealObject realObject = [[MyRealObject alloc] init];
[array replaceObjectAtIndex:index withObject:realObject];
}
** edit summary ** edited to initialize the array using a loop (thanks bbum).
**编辑汇总**,使用循环(感谢bbum)初始化数组。
#2
3
NSMutableArray doesn't support sparse arrays. Thus, you could pre-seed the array with NSNull instances (or some other "no object" marker). Something like:
NSMutableArray不支持稀疏数组。因此,您可以使用NSNull实例(或其他“no object”标记)预先对数组进行播种。喜欢的东西:
a = [NSMutableArray array];
for(int i = 0; i<numberNeeded; i++) [a addObject:[NSNull null]];
Or, if your array is going to be truly sparse, consider the use of some kind of map instead. NSMutableDictionary will work, but requires objects for keys and all that boxing/un-boxing is painful in some cases. Alternatively, a CFDictionary can easily be configured to use integer keys with object values.
或者,如果你的数组是真正稀疏的,可以考虑使用某种映射。NSMutableDictionary可以工作,但是需要键的对象,而且在某些情况下,所有的装箱/拆箱都很痛苦。另外,CFDictionary可以轻松配置为使用带有对象值的整数键。
While a dictionary is obviously slower for lookup-by-index, that performance difference is unlikely to cause a problem in most cases (but not all).
虽然字典的查找索引速度明显较慢,但在大多数情况下,性能差异不太可能导致问题(但并非全部)。
#3
0
What about [NSMutableArray arrayWithCapacity:numberOfRows]
?
那么[NSMutableArray arrayWithCapacity:numberOfRows]呢?
https://developer.apple.com/library/mac/文档/可可/引用/ /类/ NSMutableArray_Class /引用/ Reference.html基础
#1
7
The idiomatic solution in Objective C is to use NSNull
:
Objective C中的惯用方法是使用NSNull:
The NSNull class defines a singleton object used to represent null values in collection objects (which don’t allow nil values).
NSNull类定义一个单例对象,用于表示集合对象中的空值(不允许使用nil值)。
Create your NSMutableArray
, and fill it up with [NSNull null]
objects:
创建NSMutableArray,并用[NSNull null]对象填充:
NSMutableArray *array = [NSMutableArray arrayWithCapacity:N];
for (int i = 0 ; i != 10 ; [a addObject:[NSNull null]], i++);
When you check for the presence or absence of an object in your NSMutableArray
, compare the object at index to [NSNull null]
: if they are the same, replace with a real object; otherwise, the real object is already there.
当您检查NSMutableArray中是否存在对象时,将索引处的对象与[NSNull null]进行比较:如果它们是相同的,则用一个真实的对象替换;否则,真正的对象已经在那里了。
if ([array objectAtIndex:index] == [NSNull null]) {
MyRealObject realObject = [[MyRealObject alloc] init];
[array replaceObjectAtIndex:index withObject:realObject];
}
** edit summary ** edited to initialize the array using a loop (thanks bbum).
**编辑汇总**,使用循环(感谢bbum)初始化数组。
#2
3
NSMutableArray doesn't support sparse arrays. Thus, you could pre-seed the array with NSNull instances (or some other "no object" marker). Something like:
NSMutableArray不支持稀疏数组。因此,您可以使用NSNull实例(或其他“no object”标记)预先对数组进行播种。喜欢的东西:
a = [NSMutableArray array];
for(int i = 0; i<numberNeeded; i++) [a addObject:[NSNull null]];
Or, if your array is going to be truly sparse, consider the use of some kind of map instead. NSMutableDictionary will work, but requires objects for keys and all that boxing/un-boxing is painful in some cases. Alternatively, a CFDictionary can easily be configured to use integer keys with object values.
或者,如果你的数组是真正稀疏的,可以考虑使用某种映射。NSMutableDictionary可以工作,但是需要键的对象,而且在某些情况下,所有的装箱/拆箱都很痛苦。另外,CFDictionary可以轻松配置为使用带有对象值的整数键。
While a dictionary is obviously slower for lookup-by-index, that performance difference is unlikely to cause a problem in most cases (but not all).
虽然字典的查找索引速度明显较慢,但在大多数情况下,性能差异不太可能导致问题(但并非全部)。
#3
0
What about [NSMutableArray arrayWithCapacity:numberOfRows]
?
那么[NSMutableArray arrayWithCapacity:numberOfRows]呢?
https://developer.apple.com/library/mac/文档/可可/引用/ /类/ NSMutableArray_Class /引用/ Reference.html基础