NSMutableArray不保留方法外的对象

时间:2013-04-02 01:02:05

标签: iphone objective-c nsmutablearray nsarray

在我的-viewDidLoad方法中,我初始化了许多NSMutableDictionaries,并将它们添加到类头文件中通过NSMutableArray声明的初始化@property。相关代码如下所示。简而言之,我正在从HTML网页上搜索信息。

 NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
_regionalDicts = [[NSMutableArray alloc] init];

for (int i = 0; i < [strings count]; i++) {
    NSString *str = [strings objectAtIndex:i];
    //Property parser:
    if ([str rangeOfString:@"<td>"].location != NSNotFound) {
        NSString *parsedTD1 = [str stringByReplacingOccurrencesOfString:@"<td>" withString:@""];
        NSString *parsedTD2 = [parsedTD1 stringByReplacingOccurrencesOfString:@"</td>" withString:@""];
        NSString *parsedTD3 = [parsedTD2 stringByReplacingOccurrencesOfString:@"&nbsp;" withString:@"\n"];


        NSString *final = [parsedTD3 stringByReplacingOccurrencesOfString:@"\t" withString:@""];

        //NSLog(@"Final string: %@", final);

        if ([final isEqualToString:@""]) {
            continue;
        }


        if (gotEventType == NO) {
            gotEventType = YES;
            [dict setObject:final forKey:@"type"];
            continue;
        }

        if (gotRegional == YES && gotLocation == NO) {
            gotLocation = YES;
            [dict setObject:final forKey:@"location"];
            continue;
        }
        if (gotLocation == YES && gotCity == NO) {
            gotCity = YES;
            NSString *cityToReturn = [final stringByReplacingOccurrencesOfString:@"\n" withString:@""];
            [dict setObject:cityToReturn forKey:@"city"];
            continue;
        }     
        if (gotRegional == YES && gotEventType == YES && gotCity == YES && gotLocation == YES && gotURL == YES) {
            gotRegional = NO;
            gotEventType = NO;
            gotCity = NO;
            gotLocation = NO;
            gotURL = NO;

            NSLog(@"Regional: %@", [dict objectForKey:@"regional"]);
            NSLog(@"Type: %@", [dict objectForKey:@"type"]);
            NSLog(@"City: %@", [dict objectForKey:@"city"]);

            //Testing to see if anything is nil
            NSLog(@"Location: %@\n", [dict objectForKey:@"location"]);
            if (!_regionalDicts) {
                NSLog(@"Dict is nil");
            }
            [_regionalDicts addObject:dict];
            NSLog(@"Objects in array: %u", [_regionalDicts count]);
            NSMutableDictionary *tempDict = [_regionalDicts objectAtIndex:[_regionalDicts count]-1];
            NSLog(@"Regional in array: %@", [tempDict objectForKey:@"regional"]);
            [dict removeAllObjects];

            continue;
        }

很明显生成的字典是在_regionalDicts可变数组中生成并保留的,该数组在头文件中声明如下:

@property (strong, nonatomic) IBOutlet NSMutableArray *regionalDicts;

但是,当我尝试将信息传递到同一类中的表视图单元格时,字典的内容为空。数组中的对象与我期望的字典一样多,但它们不包含任何内容。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    if (_regionalDicts) {
        NSMutableDictionary *dict = [_regionalDicts objectAtIndex:0];
        NSLog(@"Setting label %@", [dict objectForKey:@"city"]);
        [cell.textLabel setText:[dict objectForKey:@"regional"]];
    }

    return cell;
}

返回:

2013-04-01 19:58:50.250 MatchScrape[53570:207] Setting label (null)

我只能想象一个内存管理问题应该受到指责。当在添加方法的范围之外访问时,为什么类数组的内容无效,但允许数组保留相同的计数?

1 个答案:

答案 0 :(得分:4)

您似乎相信将字典添加到数组实际上并不是将字典添加到数组中,而是添加字典的副本。你可能正在考虑它如何在像C ++这样的语言中运行 - 但这不是它在这里的工作方式。请记住,Objective-C对象总是通过引用访问:您永远不会将对象本身直接存储在变量或数组中 - 您只是在指向实际对象的指针周围移动,而实际对象通常存在于堆上。

因此,当您向数组添加_dict时,数组中的那个是_dict引用的完全相同的对象。你对该词典所做的任何事情 - 无论你使用什么参考 - 都将反映在引用字典的其他地方,因为它是相同的字典。你还没有复制它。因此,当你执行[_dict removeAllObjects]时,会从字典中删除所有对象,并最终得到一个包含相同空字典的数组。