我有一部分代码有时会在客户端的OSX系统上崩溃,但我无法重现崩溃。我只有很少的假设,但我不想盲目修复。我只想通过修复确信:
+ (NSArray *)loginItems:(NSError *__autoreleasing *)error {
LSSharedFileListRef list = [self loginItemsFileListRef];
NSMutableArray *result = [NSMutableArray array];
NSArray *items = [self loginItemsForFileListRef:list];
CFRelease(list);
for (id item in items) {
LSSharedFileListItemRef itemRef = (__bridge LSSharedFileListItemRef)item;
[result addObject:[self loginItemFromItemRef:itemRef]];
}
return result;
}
+ (NSDictionary *)loginItemFromItemRef:(LSSharedFileListItemRef)itemRef {
NSMutableDictionary *itemDict = [NSMutableDictionary dictionary];
// Name
CFStringRef nameRef = LSSharedFileListItemCopyDisplayName(itemRef);
if (nameRef) {
NSString *name = (__bridge NSString *)nameRef;
itemDict[RESLoginItemsNameKey] = name.stringByDeletingPathExtension;
CFRelease(nameRef);
}
// Path
CFURLRef URLRef = NULL;
if (LSSharedFileListItemResolve(itemRef, 0, &URLRef, NULL) == noErr) {
if (URLRef) {
NSURL *URL = (__bridge NSURL *)URLRef;
NSString *path = URL.path;
if (path) {
itemDict[RESLoginItemsPathKey] = path;
}
CFRelease(URLRef);
}
}
// Hidden
CFBooleanRef hiddenRef = LSSharedFileListItemCopyProperty(itemRef,
kLSSharedFileListLoginItemHidden);
if (hiddenRef) {
if (hiddenRef == kCFBooleanTrue) {
itemDict[RESLoginItemsHiddenKey] = @YES;
}
CFRelease(hiddenRef);
}
return itemDict;
}
loginItems 中的崩溃:即 SharedFileListItemDeallocate 导致崩溃。当NSArray的物品自动释放时。我想:
SSharedFileListItemRef itemRef = (__bridge LSSharedFileListItemRef)item;
打破ARC行为,当循环结束时,它导致释放数组的具体项目。第二个版本将在函数返回时被调用,这将导致崩溃。
有人可以证明或反驳我的想法吗?感谢。
答案 0 :(得分:0)
我认为问题在于您在使用
返回的项目之前发布了list
[self loginItemsForFileListRef:list]
如果返回的项取决于list
是否有效,因为list
的发布也可能触发items
的释放,那么当您尝试迭代返回时可能会崩溃项目。尝试在迭代list
的for循环之后移动items
的版本。如果你试图过度使用内存使用,有时你会被咬伤。