本文介绍了一个简单的代码在GC下可以正常工作,但在ARC中开始崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下简单的检查我的应用程序是否设置为在登录时启动"代码.在垃圾收集下工作正常.但是,由于我开始使用ARC(并在必要时插入了"__bridge"),因此代码是随机启动的,并且意外地崩溃了.根据堆栈跟踪,代码在某些CFRelease期间崩溃.有什么想法可能导致这种情况在ARC下发生吗?

I have the following simple "check whether my app is set to launch at login" code. It worked fine under garbage collection. However, since I started using ARC (and inserted the "__bridge" as necessary), the code started randomly and unpredictably crashing. According to the stack trace, the code crashes during some CFRelease. Any ideas what might be causing this to happen under ARC?

- (BOOL)loginItemExists
{
  NSString *appPath = [[NSBundle mainBundle] bundlePath];
  LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL,
                                     kLSSharedFileListSessionLoginItems, NULL);
  BOOL found = NO;  
  UInt32 seedValue;
  CFURLRef thePath;
  CFArrayRef loginItemsArray = LSSharedFileListCopySnapshot(loginItems,
                                                              &seedValue);
  for (id item in (__bridge NSArray *)loginItemsArray)
  {    
    LSSharedFileListItemRef itemRef = (__bridge LSSharedFileListItemRef)item;
    if (LSSharedFileListItemResolve(itemRef, 0, &thePath, NULL) == noErr)
    {
      if ([[(__bridge NSURL *)thePath path] hasPrefix:appPath])
        found = YES;
    }

    //docs for LSSharedFileListItemResolve say we should release the CFURLRef
    if (thePath != NULL)
      CFRelease(thePath);

    if (found)
      break;
  }

  CFRelease(loginItemsArray);
  CFRelease(loginItems);
  return found;
}

推荐答案

如果项无法解决,您将在第二次通过循环获得双重豁免.在开始时以及在释放它之后将ThePath设置为nil,这将解决崩溃问题.

You'll get a double-free here the second time through the loop if the item doesn't resolve. Set thePath to nil at the beginning and also after releasing it and that will fix the crash.

这篇关于一个简单的代码在GC下可以正常工作,但在ARC中开始崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 01:05