iOS - 如果仅在设备上运行,我的应用程序崩溃内存错误

时间:2015-05-19 08:26:16

标签: ios xcode memory crash

我的应用程序在模拟器上运行完美。 但是当我在设备上运行它进行测试时,应用程序崩溃了。

显示的错误:

  

“malloc:*对象的错误0x17415d0c0:无效指针从空闲列表中出列*在malloc_error_break中设置断点以进行调试”;

有时会发生另一个错误:

  

“Thread 6 com.apple.NSURLConnectionLoader:Program received signal:EXC_BAD_ACCESS”

这两个错误是随机的,它发生在应用程序运行两三分钟后。

我搜索了Google并找到了一些解决方案。 它说在malloc_error_break中设置一个断点来调试,但这只适用于模拟器。即使我设置malloc_error_break,应用程序仍然粉碎,它不会显示任何内容,我只能看到该错误消息。

这是一个很大的项目,我真的不知道代码的哪一部分会导致问题以及我需要发布哪部分代码。 但我怀疑其中一个类,我的'SynchroningView'。 如果只有我的应用程序与服务器同步,则会显示此视图。这意味着该视图几乎包含在我项目中的所有Viewcontroller中。

这是我的'SynchroningView'类:

“SynchroningView.h”

#import <UIKit/UIKit.h>
@class SynchroningView;

@protocol SynchroningViewDelegate
@optional
- (void)SynchroningViewCancelButtonDidClicked:(SynchroningView *)synchroningView;
- (void)SynchroningViewStartTherapyButtonDidClicked:(SynchroningView *)synchroningView;
@end



@interface SynchroningView : UIView <DataManagerDelegate>

@property (nonatomic, assign) id<SynchroningViewDelegate>delegateCustom;

@property (nonatomic, retain) UIButton *containerButton;

@property (nonatomic, retain) Patient *singlePatient;





- (instancetype)initWithFrame:(CGRect)frame;

- (void)showInView:(UIView *)view;

- (void)dismissMenuPopover;

@end

SynchroningView.m

#import "SDDemoItemView.h"
#import "SDPieLoopProgressView.h"



#define Directory_Document  [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]

#define FileName_Image_SynchroningView_BackGroundImageName @"SynchroningView_BackGroundImage"

#define FilePath_Image_SynchroningView_BackGroundImageName [Directory_Document stringByAppendingPathComponent:FileName_Image_SynchroningView_BackGroundImageName]



@interface SynchroningView ()

@property   (nonatomic, strong) DataManager*    dataManager;

@property   (nonatomic, retain) UILabel*    messageLabel;

@property   (nonatomic, retain) UIButton*   CancelButton;
@property   (nonatomic, retain) CoolButton* ConfirmButton;
@property   (nonatomic, retain) CoolButton* startTherapyButton;

@property   (nonatomic, strong) SDDemoItemView* demoProgressView;

@end

@interface SynchroningView ()
{
    BOOL    _blinking;

    NSTimer *timer;
}
@end

@implementation SynchroningView

-(void)dealloc
{

}
//get the background Image, make it blur and save it. In this way I do not have to use Blur function everytim, I use the blured image directly
- (UIImage *)getBackGroundImage
{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:FilePath_Image_SynchroningView_BackGroundImageName]) {
        return [UIImage imageWithContentsOfFile:FilePath_Image_SynchroningView_BackGroundImageName];
    }
    else{
        UIImage *backImage = [UIImage imageWithContentsOfFile:kBackgroundImagePath];
        backImage = [backImage blurWithFloat:20.0f];

        NSData * binaryImageData = UIImagePNGRepresentation(backImage);

        if ([binaryImageData writeToFile:FilePath_Image_SynchroningView_BackGroundImageName atomically:YES]) {
            return backImage;
        }
    }


    return [UIImage imageWithContentsOfFile:kBackgroundImagePath];
}

-(instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    if (self) {

        _blinking = NO;
        self.dataManager = [[DataManager alloc] init];
        self.dataManager.DelegateCustom = self;



        self.backgroundColor = [UIColor clearColor];






        self.containerButton = [[UIButton alloc] init];
        [self.containerButton setBackgroundColor:RGBA_Custom(0, 0, 0, 0.6f)];
        [self.containerButton setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin];




        UIView *shadowView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
        [self addSubview:shadowView];
        shadowView.backgroundColor = RGBA_Custom(230, 249, 251, 0.96f);
//        shadowView.layer.borderWidth = 2*IPAD;
//        shadowView.layer.borderColor = [RGBA_Custom(199, 199, 199, 1.0f) CGColor];
        shadowView.layer.shadowColor = [UIColor blackColor].CGColor;
        shadowView.layer.shadowOpacity = 0.4;
        shadowView.layer.shadowRadius = 4*IPAD;
        shadowView.layer.shadowOffset = CGSizeMake(4.0f*IPAD, 4.0f*IPAD);
        shadowView.layer.cornerRadius = 6*IPAD;
        shadowView.userInteractionEnabled = NO;




        UIImageView *backGround = [[UIImageView alloc] initWithImage:[self getBackGroundImage]];
        backGround.frame = CGRectMake(0, 0, shadowView.frame.size.width, shadowView.frame.size.height);
        backGround.backgroundColor = [UIColor clearColor];
        [shadowView addSubview:backGround];
        backGround.layer.cornerRadius = shadowView.layer.cornerRadius;
        backGround.layer.masksToBounds = YES;




        ImageWIDTH_ = self.frame.size.height*0.3;
        self.demoProgressView =[SDDemoItemView demoItemViewWithClass:[SDPieLoopProgressView class]];
        self.demoProgressView.frame = CGRectMake((self.frame.size.width - ImageWIDTH_)/2,
                                                 kFromLeft,
                                                 ImageWIDTH_,
                                                 ImageWIDTH_);
        [self addSubview:self.demoProgressView];




        self.messageLabel = [[UILabel alloc] initWithFrame:CGRectMake(kFromLeft,
                                                                  self.demoProgressView.frame.origin.y + self.demoProgressView.frame.size.height + kFromLeft,
                                                                  self.frame.size.width - kFromLeft*2,
                                                                  self.frame.size.height - (self.demoProgressView.frame.origin.y + self.demoProgressView.frame.size.height + kFromLeft*2))];
        self.messageLabel.backgroundColor = [UIColor clearColor];
        self.messageLabel.textColor = [UIColor blackColor];
        self.messageLabel.textAlignment = NSTextAlignmentCenter;
        self.messageLabel.numberOfLines = 0;
        self.messageLabel.lineBreakMode = NSLineBreakByWordWrapping;
        self.messageLabel.font = [UIFont boldSystemFontOfSize:kIPAD ? 20:12];
        self.messageLabel.text = @"";
        self.messageLabel.adjustsFontSizeToFitWidth = YES;
        [self addSubview:self.messageLabel];









        CGFloat BtnHeight = kIPAD ? 40  : 30;
        self.CancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
        self.CancelButton.frame = CGRectMake(self.frame.size.width - kFromLeft*0.5 - BtnHeight,
                                             kFromLeft*0.5,
                                             BtnHeight,
                                             BtnHeight);
        self.CancelButton.backgroundColor = [UIColor clearColor];
        [self.CancelButton setImage:[[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"utilities_close" ofType:@"png"]] forState:UIControlStateNormal];
        [self.CancelButton addTarget:self action:@selector(pressCancelButton:) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:self.CancelButton];




        BtnHeight = kIPAD ? 70  : 50;
        CGFloat BtnWidth  = self.frame.size.width/4;
        NSString*   ConfirmButtonStr = NSLocalizedString(@"Confirm", nil);
        ExpectedSize = [ConfirmButtonStr sizeWithFont:self.messageLabel.font constrainedToSize:CGSizeMake(VIEW_WIDTH, BtnHeight) lineBreakMode:NSLineBreakByWordWrapping];
        ExpectedSize = CGSizeMake(ExpectedSize.width + 30*IPAD, ExpectedSize.height);
        self.ConfirmButton = [CoolButton buttonWithType:UIButtonTypeCustom];
        self.ConfirmButton.frame = CGRectMake((self.frame.size.width - ExpectedSize.width)/2,
                                              self.frame.size.height - BtnHeight - kFromLeft,
                                              ExpectedSize.width,
                                              BtnHeight);
        self.ConfirmButton.titleLabel.font = self.messageLabel.font;
        [self.ConfirmButton setTitle:ConfirmButtonStr forState:UIControlStateNormal];
        [self.ConfirmButton addTarget:self action:@selector(pressConfirmButton:) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:self.ConfirmButton];








        BtnWidth = self.frame.size.width*0.6;
        NSString*   startTherapyButtonStr = NSLocalizedString(@"StartTerapia", nil);
        ExpectedSize = [startTherapyButtonStr sizeWithFont:self.messageLabel.font constrainedToSize:CGSizeMake(VIEW_WIDTH, BtnHeight) lineBreakMode:NSLineBreakByWordWrapping];
        ExpectedSize = CGSizeMake(ExpectedSize.width + 30*IPAD, ExpectedSize.height);
        self.startTherapyButton = [CoolButton buttonWithType:UIButtonTypeCustom];
        self.startTherapyButton.frame = CGRectMake((self.frame.size.width - ExpectedSize.width)/2,
                                                   self.ConfirmButton.frame.origin.y,
                                                   ExpectedSize.width,
                                                   self.ConfirmButton.frame.size.height);
        self.startTherapyButton.titleLabel.font = self.messageLabel.font;
        [self.startTherapyButton setTitle:startTherapyButtonStr forState:UIControlStateNormal];
        [self.startTherapyButton addTarget:self action:@selector(startTherapyButtonDidClicked:) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:self.startTherapyButton];





        self.CancelButton.alpha         = 0.0;
        self.ConfirmButton.alpha        = 0.0;
        self.startTherapyButton.alpha   = 0.0;





        if (self.dataManager.firstSynchronizationAgain == 1 && [AccessedInfo getAccessedInfo]) {
            UILabel *alertInfoLabel = [[UILabel alloc] initWithFrame:CGRectMake(kFromLeft,
                                                                                0,
                                                                                self.frame.size.width - kFromLeft*2,
                                                                                VIEW_HEIGHT)];
            alertInfoLabel.backgroundColor = [UIColor clearColor];
            alertInfoLabel.textColor = COLOR_CIRCLE;
            alertInfoLabel.textAlignment = NSTextAlignmentCenter;
            alertInfoLabel.numberOfLines = 0;
            alertInfoLabel.lineBreakMode = NSLineBreakByWordWrapping;
            alertInfoLabel.font = [UIFont systemFontOfSize:self.startTherapyButton.titleLabel.font.pointSize-2];
            alertInfoLabel.text = NSLocalizedString(@"SynchronizingNew", nil);
            ExpectedSize = [alertInfoLabel.text sizeWithFont:alertInfoLabel.font constrainedToSize:alertInfoLabel.frame.size lineBreakMode:NSLineBreakByWordWrapping];
            alertInfoLabel.frame = CGRectMake(alertInfoLabel.frame.origin.x,
                                              self.startTherapyButton.frame.origin.y - ExpectedSize.height - IPAD*2,
                                              alertInfoLabel.frame.size.width,
                                              ExpectedSize.height);
            [self addSubview:alertInfoLabel];

        }





        [self.containerButton addSubview:self];
    }

    return self;
}
//show the synchronization result message
- (void)setMessageLabelString:(NSString *)labelName
{
    self.messageLabel.text = labelName;
    ExpectedSize = [labelName sizeWithFont:self.messageLabel.font constrainedToSize:CGSizeMake(self.messageLabel.frame.size.width, VIEW_HEIGHT) lineBreakMode:NSLineBreakByWordWrapping];
    self.messageLabel.frame = CGRectMake(self.messageLabel.frame.origin.x,
                                     self.messageLabel.frame.origin.y,
                                     self.messageLabel.frame.size.width,
                                     ExpectedSize.height);


    timer = [NSTimer scheduledTimerWithTimeInterval:0.8 target:self selector:@selector(MessageLabelBlinking) userInfo:nil repeats:YES];

//    self.messageLabel.adjustsFontSizeToFitWidth = YES;
}
- (void)MessageLabelBlinking
{
    if (_blinking) {
        NSString *threeDot = @".....";
        if ([self.messageLabel.text rangeOfString:threeDot].location == NSNotFound) {
            self.messageLabel.text = [self.messageLabel.text stringByAppendingString:@"."];
        }
        else{
            self.messageLabel.text = [self.messageLabel.text stringByReplacingOccurrencesOfString:threeDot withString:@""];
        }
    }
    else{
        [timer invalidate];
        timer = nil;
    }
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/
//init the data processing block
- (void)initCustomOtherParameters
{
    self.dataManager.DelegateCustom = self;

    self.dataManager.blockProcessingData = ^(float allCommand, float restCommand){
        if (allCommand == 0) {
            [[SingletonOperationQueue mainQueue] addOperationWithBlock:^{
                self.demoProgressView.progressView.progress = 1;
                NSString *messageStr = [NSLocalizedString(@"SuccessfulSynchronized", nil) stringByAppendingFormat:@"\n%@", NSLocalizedString(@"EmptyTherapy", nil)];
                [self setMessageLabelString:messageStr];
                _blinking = NO;
                self.CancelButton.alpha         = 1.0;
            }];
        }
        else{
            float percenAger = (restCommand/allCommand);
            percenAger = 1 - percenAger;

            [[SingletonOperationQueue mainQueue] addOperationWithBlock:^{
                self.demoProgressView.progressView.progress = percenAger;
                if (restCommand == 0) {
                    [self downloadZipFile];
                }
            }];
        }
    };

    [Patient RemovePatient];

    [self.singlePatient SavePatient];
}
- (void)showInView:(UIView *)view
{
    self.transform = CGAffineTransformScale(self.transform, 0.8, 0.8);

    self.containerButton.alpha = 0.0f;
    self.containerButton.frame = view.bounds;

    [view addSubview:self.containerButton];

    [UIView animateWithDuration:0.15 animations:^{
        self.containerButton.alpha = 1.0f;
        self.transform = CGAffineTransformScale(self.transform, 1.4, 1.4);

    }completion:^(BOOL finished) {
        if (finished) {
            [UIView animateWithDuration:0.20 animations:^{
                self.transform = CGAffineTransformIdentity;
            }];

            [self sendConnectionTestRequest];
        }
        else{
            self.transform = CGAffineTransformIdentity;
            [self sendConnectionTestRequest];
        }
    }];
}
- (void)dismissMenuPopover
{
    [self hide];
}
- (void)hide
{
    [UIView animateWithDuration:0.25 animations:^{
        self.transform = CGAffineTransformScale(self.transform, 0.8, 0.8);
        self.containerButton.alpha = 0.0f;
    }completion:^(BOOL finished) {
        if (finished) {
            [self.containerButton removeFromSuperview];
        }
    }];
}

- (void)pressCancelButton:(UIButton *)button
{
    [self.dataManager CommunicationCancel];

    [self.delegateCustom SynchroningViewCancelButtonDidClicked:self];
}
- (void)startTherapyButtonDidClicked:(UIButton *)button
{
    [self.delegateCustom SynchroningViewStartTherapyButtonDidClicked:self];
}
- (void)pressConfirmButton:(UIButton *)button
{
    [UIView animateWithDuration:0.25 animations:^{
        self.CancelButton.alpha  = 0.0;
        self.ConfirmButton.alpha = 0.0;
    }];



    [self sendRegistrationRequestConfirm:YES];
}
#pragma mark - Communication
- (void)sendConnectionTestRequest
{
    [self initCustomOtherParameters];

    _blinking = YES;

    [self setMessageLabelString:NSLocalizedString(@"StartRegistration", nil)];

    [self.dataManager sendRequestCommand:kConnectionTest];
}
- (void)sendRegistrationRequestConfirm:(BOOL)Confirm
{
    [self setMessageLabelString:NSLocalizedString(@"StartRegistration", nil)];
    NSString *registrationResult = [self.dataManager RegisterTheUSER_Confirm:Confirm];
    [self processLogInResult:registrationResult];
}
- (void)processLogInResult:(NSString *)logInResult
{
    if ([logInResult isEqual:@"1"]) {
        if ([self.dataManager DataInitialization]) {
            [self.dataManager DataInitializationForFakeUser];

            [self.singlePatient SavePatient];

            [self startTherapyButtonDidClicked:nil];
        }
    }
    else if ([logInResult isEqual:@"2"]) {
        if ([self.dataManager DataInitialization]) {
            self.singlePatient.record7_AuthenticatedUser = YES;

            [self.singlePatient SavePatient];

            [self.dataManager sendRequestCommand:kNewDataAvailable];
        };
    }
    else if ([logInResult intValue] == DEVICE_NOT_REGISTERED){
        logInResult = NSLocalizedString(@"105", nil);
        _blinking = NO;
        [self setMessageLabelString:logInResult];
        [UIView animateWithDuration:0.25 animations:^{
            self.CancelButton.alpha  = 1.0;
            self.ConfirmButton.alpha = 1.0;
        }];
    }
    else if ([logInResult isEqualToString:kNO]){
        _blinking = NO;
        [self setMessageLabelString:@"Cannot find the Error "];
        [UIView animateWithDuration:0.25 animations:^{
            self.CancelButton.alpha  = 1.0;
        }];
    }
    else{
        _blinking = NO;
        [self setMessageLabelString:logInResult];
        [UIView animateWithDuration:0.25 animations:^{
            self.CancelButton.alpha  = 1.0;
        }];
    }
}

- (void)downloadZipFile
{
    self.demoProgressView.progressView.progress = 1.0;

    sleep(0.4);

    [self setMessageLabelString:NSLocalizedString(@"Loading Data", nil)];
    self.demoProgressView.progressView.progress = 0.0;
    self.dataManager.blockProcessingDataPercentAge = ^(float percentAge, NSString *fileName){

        if ([fileName isEqualToString:kaderenzainfo]) {
            [[SingletonOperationQueue mainQueue] addOperationWithBlock:^{
                self.demoProgressView.progressView.progress = percentAge;
                NSLog(@"%f", percentAge);
                if (percentAge == 0.5) {
                    sleep(0.4);
                    NSString *aderenzainfoFilePath =  [[NSUserDefaults standardUserDefaults] objectForKey:kaccertamentiinfo];
                    [self.dataManager downloadZipFile:aderenzainfoFilePath fileName:kaccertamentiinfo];
                }
            }];
        }
        else if ([fileName isEqualToString:kaccertamentiinfo]){
            [[SingletonOperationQueue mainQueue] addOperationWithBlock:^{
                self.demoProgressView.progressView.progress = 0.5 + percentAge;
                if (0.5 + percentAge >= 1.0) {

                    _blinking = NO;
                    self.CancelButton.alpha = 1.0;

                    if ([Patient getPatient].record_patientStatus == PatientStatusSuspendedType) {
                        [self setMessageLabelString:NSLocalizedString(@"SuspendedPatient", nil)];
                    }
                    else if ([Patient getPatient].record_patientStatus == PatientStatusDeletedType){
                        [self setMessageLabelString:NSLocalizedString(@"DeletedPatient", nil)];
                    }
                    else if ([Patient getPatient].record_patientStatus == PatientStatusActiveType){
                        [self setMessageLabelString:NSLocalizedString(@"SuccessfulSynchronized", nil)];
                        self.startTherapyButton.alpha = 1.0;
                    }
                }
            }];
        }
    };



    NSString *aderenzainfoFilePath =  [[NSUserDefaults standardUserDefaults] objectForKey:kaderenzainfo];
    [self.dataManager downloadZipFile:aderenzainfoFilePath fileName:kaderenzainfo];
}
#pragma mark - DataManagerDelegate
- (void)CommunicationConnectionTest:(BOOL)connected
{
    if (connected) {
        [self sendRegistrationRequestConfirm:NO];
    }
    else{
        [self setMessageLabelString:NSLocalizedString(@"connectionTestFail", nil)];
        [UIView animateWithDuration:0.25 animations:^{
            self.CancelButton.alpha  = 1.0;
        }];
        _blinking = NO;
    }
}
- (void)CommunicationSendRequestCommandName:(NSString *)commandName
{
    if ([commandName isEqualToString:kNewDataAvailable]) {
        [self setMessageLabelString:NSLocalizedString(@"Synchronizing", nil)];
    }
}
- (void)CommunicationReceiveResponseWithOKCommandName:(NSString *)commandName
{

}
- (void)CommunicationReceiveResponseWithRequestError:(NSString *)commandName
{
    [self setMessageLabelString:NSLocalizedString(@"NetworkConnectionError", nil)];
    _blinking = NO;
    [UIView animateWithDuration:0.25 animations:^{
        self.CancelButton.alpha  = 1.0;
    }];
}
- (void)CommunicationReceiveResponseCommandName:(NSString *)commandName WithErrorCode:(int)errorCode withErrorDescription:(NSString *)errorDescription
{
    [self setMessageLabelString:NSLocalizedString(@"NewDataAvaiableErrorCode", nil)];
    _blinking = NO;
    [UIView animateWithDuration:0.25 animations:^{
        self.CancelButton.alpha  = 1.0;
    }];
}
-(void)CommunicationZipFileFailDownload
{
    [self setMessageLabelString:NSLocalizedString(@"ZipFileDownloadFail", nil)];
    _blinking = NO;
    [UIView animateWithDuration:0.25 animations:^{
        self.CancelButton.alpha  = 1.0;
    }];
}
-(void)CommunicationZipFileIsNotReadAble
{
    [self setMessageLabelString:NSLocalizedString(@"ZipFileUnzippedFail", nil)];
    _blinking = NO;
    [UIView animateWithDuration:0.25 animations:^{
        self.CancelButton.alpha  = 1.0;
    }];
}
@end

2 个答案:

答案 0 :(得分:0)

模拟器的存储器= Pc的RAM,即4或6 gb等 和设备最大只有1 GB。在运行应用程序的Xcode中,您需要单击Debug Navigator,然后单击“内存”,它将显示应用程序的内存消耗。

要查看代码中的内存泄漏 - 您必须使用内存工具,例如Instruments。

答案 1 :(得分:0)

我终于解决了它

在我的加密和解密功能中,我有这个:

Byte *buffer    = (Byte*)malloc(asciiDataLength);

用缓冲区处理后,我将其转换为NSData:

NSData *plainData = [NSData dataWithBytesNoCopy:buffer length:asciiDataLength freeWhenDone:YES];

此代码导致我的应用程序不断粉碎,我将其更改为

NSData *plainData = [NSData dataWithBytes:buffer length:asciiDataLength];
free(buffer);

然后我的应用程序再也不会粉碎了。

所以我必须自己释放字节,ARC不会为我释放它。