저는 Raphael Cruzeiro의 PDF Annotator 코드를 사용하여 ARC가 꺼져 있고 오래된 장치를 지원하기 위해 많은 메모리 누수가 있음을 발견했습니다. 대부분을 패치 한 후, 나는 지난 커플에게로 내려 갔고, 그들은 나를 곤혹스럽게 만들었다. 따라서 PDFDocument
클래스에서 그는 CGPDFPageRef
, CGPDFDocument
및 맞춤 주석 클래스 @synthesize
'd에 대한 속성을가집니다. 나는 그의 dealloc 메소드를 릴리즈로 후 처리해야만하고 하나의 작은 문제를 제외하고는 잘 작동하는 매달려있는 포인터를 제거해야했다 : 약 3 개의 완전한 유지 해제 사이클 후에, @ annhesation 객체의 @synthesize 라인에서 충돌이 발생했다. @synthesize 중에 전송 된 할당 해제 된 객체 때문에 SIGABRT를 본 적이 없으므로 자연스럽게 어떻게 수정해야하는지 모릅니다. dealloc에서 릴리스 코드를 제거하면 누수가 발생하지만이를 그대로두면 충돌이 발생합니다. 여기에 PDFDocument 클래스의 코드가있다 : 좀비 오브젝트를 찾을 수 할당 해제 된 인스턴스로 보낸 메시지 ... @synthesize 중 보낸 메시지?
//.h
#import <Foundation/Foundation.h>
@class Annotation;
@interface PDFDocument : NSObject {
Annotation *_annotation;
}
- (id)initWithDocument:(NSString *)documentPath;
- (NSInteger) pageCount;
- (void) loadPage:(NSInteger)number;
- (BOOL)save;
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSString *hash;
@property (readwrite, nonatomic, assign) CGPDFDocumentRef document;
@property (readwrite, nonatomic, assign) CGPDFPageRef page;
@property (nonatomic, retain) NSString *version;
@property (nonatomic, assign) BOOL dirty;
@property (nonatomic, retain) Annotation *annotation;
@end
//.m
#import "PDFDocument.h"
#import "Annotation.h"
#import "HashExtensions.h"
#import "DocumentDeserializer.h"
#import "DocumentSerializer.h"
@implementation PDFDocument
@synthesize document;
@synthesize page;
@synthesize annotation = _annotation; //after 3rd cycle, it crashes here.
@synthesize name;
@synthesize hash;
@synthesize dirty;
@synthesize version;
- (id)initWithDocument:(NSString *)documentPath
{
if((self = [super init]) != NULL) {
self.name = [documentPath lastPathComponent];
if ([self.name isEqualToString:@"Musette.pdf"] || [self.name isEqualToString:@"Minore.pdf"] || [self.name isEqualToString:@"Cantata.pdf"] || [self.name isEqualToString:@"Finalé.pdf"])
{
CFURLRef ref = CFBundleCopyResourceURL(CFBundleGetMainBundle(), (CFStringRef)self.name, NULL, NULL);
self.document = CGPDFDocumentCreateWithURL(ref);
self.page = CGPDFDocumentGetPage(document, 1);
self.version = @"1.0";
DocumentDeserializer *deserializer = [[[DocumentDeserializer alloc] init] autorelease];
self.annotation = [deserializer readAnnotation:[[(NSURL*)ref absoluteString] stringByDeletingPathExtension]];
CFRelease(ref);
}
else {
CFURLRef pdfURL = (CFURLRef)[[NSURL alloc] initFileURLWithPath:documentPath];
self.document = CGPDFDocumentCreateWithURL(pdfURL);
self.page = CGPDFDocumentGetPage(document, 1);
self.version = @"1.0";
DocumentDeserializer *deserializer = [[[DocumentDeserializer alloc] init] autorelease];
self.annotation = [deserializer readAnnotation:[[(NSURL*)pdfURL absoluteString] stringByDeletingPathExtension]];
CFRelease(pdfURL);
CGPDFPageRelease(self.page);
}
}
return self;
}
- (NSInteger)pageCount
{
return CGPDFDocumentGetNumberOfPages(self.document);
}
- (void)loadPage:(NSInteger)number
{
self.page = CGPDFDocumentGetPage(document, number);
}
- (BOOL)save
{
DocumentSerializer *serializer = [[[DocumentSerializer alloc] init] autorelease];
[serializer serialize:self];
self.dirty = NO;
return !self.dirty;
}
- (void)dealloc
{
CGPDFDocumentRelease(self.document);
if (self.annotation != nil && _annotation != nil) {
[_annotation release];
self.annotation = nil;
} //my attempt to prevent the object from being over-released
self.document = nil;
self.name = nil;
[super dealloc];
}
@end
가 그럼 난 악기를 통해 실행하고, 확실히 충분히, Instruments는 할당이 해제 된 객체가 동일한 @synthesize 라인에 메시지를 보내는 발견!
누구에게 무슨 일이 벌어지고 있고 어떻게 수정해야하는지 알 수 있습니까?
1 세대 iPhone 만 ARC와 호환되지 않습니다. 왜 사용하지 않습니까? –
단지 내 자신의 환경 설정 ... ARC 리팩토링 도구가 지금 당황 스럽다는 사실과 결합되었습니다. 한숨 ... 나는 지금 개종 할거야. – CodaFi
"합성 중"오류가 발생했다고합니다. 실제로, 그것은'- (Annotation *) annotation' 또는'- (void) setAnnotation : (Annotation *)'합성 메소드 중 하나에서 충돌하는 것입니다. 이미 ivar가 벌써 석방 된 세터 일거야. – mattjgalloway