仅在设备上运行应用程序时发生崩溃问题

所以我有一个非常奇怪的问题,当我在模拟器上运行我的应用程序,并且插入iPad(在插入电缆的情况下在设备上运行应用程序)时,它一切正常。然而,在插入设备后运行,我试图使用该应用程序,它崩溃..试着看着设备崩溃日志,我看到:

Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libobjc.A.dylib                 0x3672bf78 objc_msgSend + 16
1   App                     0x000ca834 -[AHAppImageData dealloc] (AHInstagramImageData.m:122)
2   libobjc.A.dylib                 0x3672d16e _objc_rootRelease + 30
3   CoreFoundation                  0x33d792e0 CFRelease + 88
4   CoreFoundation                  0x33d8ea30 -[__NSArrayM removeObjectAtIndex:] + 288
5   CoreFoundation                  0x33d84adc -[NSMutableArray removeAllObjects] + 64
6   App                     0x000f717e -[AHImageDataSource clearDataSource] (AHImageDataSource.m:53)
7   App                     0x000c0a36 __49-[AHMainViewController loadRequestWithURLString:]_block_invoke_0 (AHMainViewController.m:91)
8   libdispatch.dylib               0x32658c52 _dispatch_call_block_and_release + 6
9   libdispatch.dylib               0x3265aee0 _dispatch_main_queue_callback_4CF$VARIANT$mp + 188
10  CoreFoundation                  0x33e032a6 __CFRunLoopRun + 1262
11  CoreFoundation                  0x33d8649e CFRunLoopRunSpecific + 294
12  CoreFoundation                  0x33d86366 CFRunLoopRunInMode + 98
13  GraphicsServices                0x37d68432 GSEventRunModal + 130
14  UIKit                           0x36820cce UIApplicationMain + 1074
15  App                     0x000b2860 main (main.m:16)
16  App                     0x000b2820 0xb1000 + 6176

任何想法为什么这只发生在设备上,而不是在插入或模拟器时运行应用程序?

根据以下评论,我展示了对此负责的代码:

 [[AHMyAppAPIClient sharedClient] getPath:requestURLPath parameters:nil 
             success:^(AFHTTPRequestOperation *operation, id response) {
                 [self.progressHUD_ hide:YES];


                 self.nextPaginationURL_ = [[response valueForKey:@"pagination"] valueForKey:@"next_url"];

                 [self.collectionView_.pullToRefreshView stopAnimating];
                 [[NSOperationQueue sharedOperationQueue] cancelAllOperations];


                 NSArray *arr = [response valueForKey:@"data"];
                 if ([arr count] > 0){
                     [[AHImageDataSource sharedDataSource] clearDataSource];
                 }


                for (NSDictionary * data in arr){
                     AHInstagramImageData * imgData = [[AHInstagramImageData alloc] initWithData:data];
                     [[AHImageDataSource sharedDataSource] addObject:imgData];
                     [imgData release];
                 }


                 dispatch_async(dispatch_get_main_queue(), ^{
                     [self.collectionView_ setContentOffset:CGPointMake(0, 0)];
                     [self.collectionView_ reloadData];

                 });

             }
             failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                 [self.progressHUD_ hide:YES];
                 NSLog(@"Error fetching user data!");
                 NSLog(@"%@", error);      

             }];

这就是我设置数据源的方式:

extern NSString * const kClearDataSource;

@interface AHImageDataSource : NSObject
+ (AHImageDataSource *)sharedDataSource;
- (void) clearDataSource;
- (void) addObject:(id) object;
- (void) addObject:(id)object atIndex:(int) index;
- (int) count;
- (id) objectAtIndex:(int) index;
@end


NSString * const kClearDataSource = @"clearDataSource";

@interface AHImageDataSource()
{
    NSMutableArray * imageDataSource_;
}

@property (nonatomic, retain) NSMutableArray * imageDataSource_;

@end

@implementation AHImageDataSource
@synthesize imageDataSource_;

+ (AHImageDataSource *)sharedDataSource {
    static AHImageDataSource *_sharedClient = nil;
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        _sharedClient = [[self alloc] init];
    });

    return _sharedClient;
}


- (id)init {
    self = [super init];
    if (!self) {
        return nil;
    }

    NSMutableArray * temp = [[NSMutableArray alloc] initWithCapacity:200];
    self.imageDataSource_  = temp;
    [temp release];


    return self;
}

-(void) clearDataSource
{
    if ([self.imageDataSource_ count] > 0){
        [self.imageDataSource_ removeAllObjects];
    }

}

- (void) addObject:(id) object
{
    [self.imageDataSource_ addObject:object];
}

- (void) addObject:(id)object atIndex:(int) index
{
    [self.imageDataSource_ insertObject:object atIndex:index];
}

- (int) count
{
    return [self.imageDataSource_ count];
}

- (id) objectAtIndex:(int) index
{
    if (index >= 0 && index < [self.imageDataSource_ count]){
        return [self.imageDataSource_ objectAtIndex:index];
    } 

    return nil;
}

- (void) dealloc
{
    [super dealloc];
    [imageDataSource_ release];
}

@end

修改</强>

看来NSZombieEnabled似乎隐藏了这个问题。当我禁用NSZombieEnabled时,它现在在模拟器和设备上崩溃。

2
额外 编辑
意见: 1
如果NSZombieEnabled隐藏了这个问题,那么它几乎肯定是双重免费的。非常奇怪的是,这个乐器模板没有拿起来...
额外 作者 MobileVet,

2 答案

我同意吉姆,看起来像是一个双重版本。

我会利用乐器的 zombie '配置文件来测试这种情况。它只能在模拟器中完成,但应该告诉你到底发生了什么。

一旦100%清楚,解决这种情况通常很容易。

1
额外
是的,但你需要使用一个特殊的仪器模板,这将使其非常清晰。我希望我可以包括一个图像...如果你点击左侧的iOS模拟器模板过滤器中的'记忆',你会看到'僵尸'作为第五个选项(第一行在第二行),它应该设置一切您。
额外 作者 MobileVet,
不能使用僵尸,因为它可以在模拟器上正常工作..不会崩溃
额外 作者 adit,
只是尝试从仪器使用NSZombies,并没有看到任何泄漏时,再现设备上的相同步骤
额外 作者 adit,
你的意思是NSZombieEnabled在方案中?
额外 作者 adit,
是的..我的乐器正在运行..它运行正常,我没有看到任何双发行版或以往
额外 作者 adit,
这很难..因为它在模拟器上正常工作,并且在设备上运行它时..我使用两种情况下的仪器上的僵尸来描述它,并没有看到任何迹象表明我是双释放任何东西..当我运行它时没有连接到电线的设备..它崩溃
额外 作者 adit,
我在上面添加了更多信息
额外 作者 adit,
它不一定在模拟器上正常工作。当你过度释放某些东西时,它是否真的崩溃真是太幸运了。过度释放仍然发生,僵尸的方法应该不管。
额外 作者 Jim,
你不是在寻找泄漏,你正在寻找双重释放,这基本上与泄漏相反。编辑您的方案并在运行部分的选项中启用僵尸对象。
额外 作者 Jim,
您可以在设备上运行代码时使用NSZombies。
额外 作者 Abizern,

它看起来像是通过将 AHInstagramImageData 的实例放入字典中而过度释放,然后降低保留计数以使其被释放。然后,当它从字典中被移除时,它会再次被释放,它会尝试为不再存在的对象释放内存。

发布代码负责人,你可能会得到更详细的帮助。一个崩溃日志本身并不足以继续。

0
额外
我添加了代码负责..希望你可以帮助更多..因为我没有看到双重版本的位置
额外 作者 adit,
我添加了如何设置数据源..让我知道如果这是你正在寻找
额外 作者 adit,
我在上面添加了关于如何定义这个属性的代码。我知道这是一种奇怪的做法
额外 作者 adit,
这是触发错误的代码,但错误可能在于您设置数据源的位置。你可以发布吗?
额外 作者 Jim,
self.imageDataSource_ = temp; 看起来不正确。您正在使用属性语法,但是使用私有的伊娃命名约定。由于你的代码编译,你使用的是一个属性,但你似乎混淆了它们之间的差异。你怎么定义这个属性?
额外 作者 Jim,