今日金句:好记心不如烂笔头
看过的知识点,过段时间,不用或者不看,太容易忘记了,为了督促自己,也为了以后的巩固,看到的知识点在这里记录一下。
NSPointerArray
A collection similar to an array, but with a broader range of available memory semantics.
一个类似于数组的集合,但是具有更广泛的内存语义。

大概就是介绍了NSPointerArray的如下几个特点:
- NSPointerArray可以存放nil
- 可以插入删除nil
- count 属性可以设置 (用nil占位)
- 可以初始化以保持对对象的强引用或弱引用,也可以根据NSPointerFunctionsOptions定义的任何内存或个性选项进行初始化
- NSCopying和NSCoding协议仅在指针数组初始化为保持对对象的强引用或弱引用时才适用
- 遵循 NSFastEnumeration,可以通过 for...in 来进行遍历
验证用nil占位
NSPointerFunctions *funcions = [NSPointerFunctions pointerFunctionsWithOptions:NSPointerFunctionsStrongMemory];
NSPointerArray *pointerArray1 = [[NSPointerArray alloc] initWithPointerFunctions:funcions];
for (int i = 0; i < 8; i++) {
CALayer *layer = [CALayer layer];
layer.backgroundColor = [UIColor clearColor].CGColor;
[pointerArray1 addPointer:(__bridge void * _Nullable)(layer)];
}
pointerArray1.count = 10;
[pointerArray1 addPointer:nil];
for (id item in pointerArray1) {
NSLog(@"%@",item);
}
NSLog(@"%@",[pointerArray1 allObjects]);
NSLog(@"%lu",(unsigned long)pointerArray1.count);
根据打印结果可知:
- allObjects 是没有值为nil的元素的
- 通过for...in 可以把包含nil的元素遍历出来

NSPointerArray的应用
其实也是我写这篇文章的起因~
是在看SDWebImage源码的时候注意到有对NSPointerArray的使用
// element is weak because operation instance is retained by SDWebImageManager's runningOperations property
// we should use lock to keep thread-safe because these method may not be acessed from main queue
- (NSPointerArray *)sd_animationOperationArray {
@synchronized(self) {
NSPointerArray *operationsArray = objc_getAssociatedObject(self, &animationLoadOperationKey);
if (operationsArray) {
return operationsArray;
}
operationsArray = [NSPointerArray weakObjectsPointerArray];
objc_setAssociatedObject(self, &animationLoadOperationKey, operationsArray, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
return operationsArray;
}
}
- (void)sd_cancelCurrentAnimationImagesLoad {
NSPointerArray *operationsArray = [self sd_animationOperationArray];
if (operationsArray) {
@synchronized (self) {
for (id operation in operationsArray) {
if ([operation conformsToProtocol:@protocol(SDWebImageOperation)]) {
[operation cancel];
}
}
operationsArray.count = 0;
}
}
}
除此之外,我们用到的其他三方库中还有FSCalendar中也用到了NSPointerArray
self.eventLayers = [NSPointerArray weakObjectsPointerArray];
for (int i = 0; i < 3; i++) {
CALayer *layer = [CALayer layer];
layer.backgroundColor = [UIColor clearColor].CGColor;
[self.contentView.layer addSublayer:layer];
[self.eventLayers addPointer:(__bridge void * _Nullable)(layer)];
}
暂时还没看到有使用其他内存语义(NSPointerFunctionsOptions)的使用,NSPointerFunctionsWeakMemory适用于ARC或GC,会在最后一次释放之后置为null.
根据SDWebImage中这句注释element is weak because operation instance is retained by SDWebImageManager's runningOperations property,也可以更好的理解NSPointerFunctionsOptions所起到的作用,以及和NSArray的区别
- 保持被添加对象的强引用或者弱引用