meh
meh

Reputation: 351

A simple code that worked fine under GC but started crashing in 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;
}

Upvotes: 2

Views: 472

Answers (2)

Ken Aspeslagh
Ken Aspeslagh

Reputation: 11594

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.

Upvotes: 4

owen gerig
owen gerig

Reputation: 6172

you could disable ARC by adding a Compiler Flag -fno-objc-arc to the specific file enter image description here

Upvotes: -1

Related Questions