从 NSMutableArray 中删除未知类型
Removing unknown type from NSMutableArray
当尝试从 NSMutableArray 中删除未知类型时,我不确定如何将项目分配给要删除的变量。我能够深入到该类型的字符串 属性 但不确定如何删除整个对象。
现在我得到的错误是:
使用未声明的标识符'item'
NSMutableArray * skProducts = response.products;
for (SKProduct * skProduct in skProducts) {
NSLog(@"Found product: %@ %@ %0.2f",
skProduct.productIdentifier,
skProduct.localizedTitle,
skProduct.price.floatValue);
if ( [skProduct.productIdentifier isEqualToString:@"com.eboticon.Eboticon.baepack1"] ) {
// do found
[skProducts removeObject: item];
} else {
// do not found
}
您当前的问题是,您从未定义 item
。
你是 (fast) enumerating 和 for (SKProduct * skProduct in skProducts) {
,所以你的意思可能是 skProduct
而不是 item
。
修复该问题后,您将收到一个新错误:在枚举数组时不允许更改数组。有关解决方案,请参阅 Best way to remove from NSMutableArray while iterating?。
单向:反向 block-based enumeration.
[skProducts enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(SKProduct * skProduct, NSUInteger idx, BOOL *stop) {
if ([skProduct.productIdentifier isEqualToString:@"com.eboticon.Eboticon.baepack1"] ) {
// do found
[skProducts removeObject: skProduct];
} else {
// do not found
}
}];
另一种方法:过滤所有没有不需要的产品标识符的产品。
[skProducts filterUsingPredicate:[NSPredicate predicateWithFormat:@"productIdentifier != %@", @"com.eboticon.Eboticon.baepack1"]];
另注:
我假设 response
属于 class SKProductsResponse
。它的 products
属性 定义为 @property(nonatomic, readonly) NSArray<SKProduct *> *products;
NSMutableArray * skProducts = response.products;
因此 skProducts
确实指向 NSArray,而不是 NSMutableArray,因为您只是键入变量,这不会转换变量指向的对象。
你想要
NSMutableArray *skProducts = [response.products mutableCopy];
在 Objective-C 中,您不能改变正在枚举的数组(并且 for...in 语法正在枚举)。你会崩溃的。
您要么需要按索引向后遍历对象,并删除不属于的对象,要么使用 NSArray
函数 filterUsingPredicate
。 filterUsingPredicate
可能是更好的方法,但我使用 NSPredicate
的频率不够高,无法立即为您提供代码。
for 循环版本可能如下所示:
if (skProducts.count == 0)
return;
for (NSInteger index = skProducts.count - 1; index >= 0; index--) {
product = skProducts[index];
if ( [skProduct.productIdentifier isEqualToString:@"com.eboticon.Eboticon.baepack1"] ) {
//Do whatever you need to do with the object before removing it
[skProducts removeObjectAtIndex: index];
}
}
当尝试从 NSMutableArray 中删除未知类型时,我不确定如何将项目分配给要删除的变量。我能够深入到该类型的字符串 属性 但不确定如何删除整个对象。
现在我得到的错误是:
使用未声明的标识符'item'
NSMutableArray * skProducts = response.products;
for (SKProduct * skProduct in skProducts) {
NSLog(@"Found product: %@ %@ %0.2f",
skProduct.productIdentifier,
skProduct.localizedTitle,
skProduct.price.floatValue);
if ( [skProduct.productIdentifier isEqualToString:@"com.eboticon.Eboticon.baepack1"] ) {
// do found
[skProducts removeObject: item];
} else {
// do not found
}
您当前的问题是,您从未定义 item
。
你是 (fast) enumerating 和 for (SKProduct * skProduct in skProducts) {
,所以你的意思可能是 skProduct
而不是 item
。
修复该问题后,您将收到一个新错误:在枚举数组时不允许更改数组。有关解决方案,请参阅 Best way to remove from NSMutableArray while iterating?。
单向:反向 block-based enumeration.
[skProducts enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(SKProduct * skProduct, NSUInteger idx, BOOL *stop) {
if ([skProduct.productIdentifier isEqualToString:@"com.eboticon.Eboticon.baepack1"] ) {
// do found
[skProducts removeObject: skProduct];
} else {
// do not found
}
}];
另一种方法:过滤所有没有不需要的产品标识符的产品。
[skProducts filterUsingPredicate:[NSPredicate predicateWithFormat:@"productIdentifier != %@", @"com.eboticon.Eboticon.baepack1"]];
另注:
我假设 response
属于 class SKProductsResponse
。它的 products
属性 定义为 @property(nonatomic, readonly) NSArray<SKProduct *> *products;
NSMutableArray * skProducts = response.products;
因此 skProducts
确实指向 NSArray,而不是 NSMutableArray,因为您只是键入变量,这不会转换变量指向的对象。
你想要
NSMutableArray *skProducts = [response.products mutableCopy];
在 Objective-C 中,您不能改变正在枚举的数组(并且 for...in 语法正在枚举)。你会崩溃的。
您要么需要按索引向后遍历对象,并删除不属于的对象,要么使用 NSArray
函数 filterUsingPredicate
。 filterUsingPredicate
可能是更好的方法,但我使用 NSPredicate
的频率不够高,无法立即为您提供代码。
for 循环版本可能如下所示:
if (skProducts.count == 0)
return;
for (NSInteger index = skProducts.count - 1; index >= 0; index--) {
product = skProducts[index];
if ( [skProduct.productIdentifier isEqualToString:@"com.eboticon.Eboticon.baepack1"] ) {
//Do whatever you need to do with the object before removing it
[skProducts removeObjectAtIndex: index];
}
}