2013-03-19 76 views
3

我正在创建一个启用了ARC的iPhone应用程序,在此我有一种情况。如何使用ARC处理iOS中的自动释放对象

在应用程序的每个页面中,正在发生Web服务调用。在此方法中,我将从数组中删除所有对象,然后再从服务器添加新值。所有工作正常,但有时应用程序崩溃在[self.myArray removeAllObjects]

我已经设置为@property myarray的@property (strong, nonatomic) NSMutableArray myArray;

我在想什么,正如我使用ARC,对象,myArray,在某些时候得到了释放,我尝试删除来自同所有对象阵列。导致这次事故,我不确定,但我没有看到任何其他原因。

所以,我正在考虑检查数组是否有效,然后删除它中的对象。我写了一个示例代码来检查不同的场景。这是它:

NSMutableArray *testArray = [[NSMutableArray alloc]initWithObjects:@"1", @"2", @"3", @"4", nil]; 

if (testArray) { 
    NSLog(@"i am alive"); 
} 

[testArray release]; 

if (testArray) { //here how to check whether this array is valid or not? 
    NSLog(@"i am alive: %@", testArray); 
}else{ 
    NSLog(@"I am dead"); 
    testArray = [[NSMutableArray alloc]initWithObjects:@"5", @"6", @"7", @"8", nil]; 
} 

[testArray release]; 
[testArray removeAllObjects]; 

我知道它会导致崩溃,但它只是为了检查。在这里,我该如何检查数组是否有效?这是一个正确的方法还是别的什么?

请指导我。
谢谢。

实际代码:

- (void)getFriendsList{ 

    BOOL netIsAvailable = [self connected]; 

    if (netIsAvailable) { 
     @try { 
      NSString *accessToken = [self getAccessToken]; 
      NSString *tokenEncoded = [accessToken stringByReplacingOccurrencesOfString:@"\"" withString:@""]; 
      NSString *finalUrl = [NSString stringWithFormat:@"%@FriendsnSongs/%@",CommonWebServiceUrl,tokenEncoded]; 
      NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:finalUrl] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10]; 
      NSURLResponse *response = nil; 
      NSError *error = nil; 
      NSData *currentResult = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; 
//   NSString* responseString = [[NSString alloc] initWithData:currentResult encoding:NSUTF8StringEncoding]; 

      if (currentResult != nil) { 
       NSDictionary* json = [NSJSONSerialization 
             JSONObjectWithData:currentResult 
             options:kNilOptions 
             error:&error]; 
       NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; 
       int statusCode = [httpResponse statusCode]; 

       NSMutableArray *match = [json valueForKey:@"FriendsnSongsResult"]; 
       if (statusCode == 200) { 
        if (self.userGuidArray) { 
         [self.albumNameArray removeAllObjects]; //here got crash 
         [self.artistNameArray removeAllObjects]; 
         [self.deviceNameArray removeAllObjects]; //here also got crash once 
         [self.nickNameArray removeAllObjects]; 
         [self.userProfileImageArray removeAllObjects]; 
         [self.songTitleArray removeAllObjects]; 
         [self.songStatusArray removeAllObjects]; 
         [self.userGuidArray removeAllObjects]; 
        } 

        for(NSArray *player in match) { 
         [self.albumNameArray addObject:[(NSArray *)player valueForKey:@"AlbumName"]]; 
         [self.artistNameArray addObject:[(NSArray *)player valueForKey:@"Artist"]]; 
         [self.nickNameArray addObject:[(NSArray *)player valueForKey:@"NickName"]]; 
         [self.userProfileImageArray addObject:[(NSArray *)player valueForKey:@"ProfileImage"]]; 
         [self.songStatusArray addObject:[(NSArray *)player valueForKey:@"Status"]]; 
         [self.songTitleArray addObject:[(NSArray *)player valueForKey:@"Title"]]; 
         [self.userGuidArray addObject:[(NSArray *)player valueForKey:@"UserGuid"]]; 
         [self.deviceNameArray addObject:[(NSArray *)player valueForKey:@"DeviceName"]]; 
        } 
        //Start timer for updating the friends list 
        if (timerActivated) 
         [self performSelectorOnMainThread:@selector(backgroundFriendsListUpdate) withObject:nil waitUntilDone:NO]; 
        //Update table if the table not in search mode 
        if (!isSearching) 
         [self performSelectorOnMainThread:@selector(updateTable) withObject:nil waitUntilDone:YES]; 
       } 
      } 
     } 
     @catch (NSException *exception) { 
      NSLog(@"Exception: %@",exception.name); 
     } 
    } 
    [DejalActivityView removeView]; 
} 

而且重要的一点是,在这个类中后台线程在每30秒运行。它会调用相同的方法来刷新表格。

+0

wt是错误的,为什么你用testArray release];即使你使用电弧? – iPatel 2013-03-19 09:29:39

+0

一旦释放,你就无法再测试它了。我更倾向于找到问题的根源,而不是围绕它跳舞。 – Bushbert 2013-03-19 09:31:49

+0

@iPatel在这个示例代码中,我没有使用ARC,我写这只是为了检查一个对象是否有效,即使在发布之后。 – Mithuzz 2013-03-19 09:33:43

回答

1

正如你在评论中所建议的那样,使用临时数组是个好主意。下面的代码将填充一个临时数组并用它来替换主线程中的数组。

NSMutableArray *tempAlbumArray = [NSMutableArray array]; 
//fill your array 
[tempAlbumArray addObject:<#some object#>]; 
dispatch_async(dispatch_get_main_queue(), ^{ 
    //replace your array with the new one 
    //this code will be executed in main thread 
    self.albumNameArray = tempAlbumArray; 
}); 
+0

谢谢你,让我试试你的代码。 – Mithuzz 2013-03-19 11:15:04

+0

截至目前该应用程序运行良好,希望这将解决这个问题。谢谢。 – Mithuzz 2013-03-19 12:31:18

4

如果您正在使用ARC然后从你的代码删除[testArray release];这条线,因为ARC处理它。否则[testArray release];写入-(void)dealloc方法。

给予条件之前删除数组值

if(myArray.count > 0)// because sometime it is good logic for us. 
    [myArray removeAllObjects]; 

然后在myArray插入数据。

+0

我也试过这个,但我仍然崩溃。我试图在释放一个数组之前和之后NSLog计算数组,我得到了相同的计数,它不是零。所以,即使我们释放一个数组后,count也是一样的? – Mithuzz 2013-03-19 09:54:47

+0

@ Mithuzz-让我知道wt是错误? – iPatel 2013-03-19 09:55:40

+0

我添加了异常断点,所以错误发生在[self.myArray removeAllObjects];而且我用try和catch,所以在异常部分,异常是NSRangeException。 – Mithuzz 2013-03-19 09:57:36