ARC在UIView子视图中不保留NSString

时间:2013-04-30 18:48:53

标签: ios objective-c nsstring automatic-ref-counting

我有一个父视图,可让您查看UITableView中的帖子。在它的导航栏中,我有一个帖子按钮,按下时会显示一个UIView子类并在屏幕顶​​部显示它。我在UIView上有一个图片,当点按它时会显示UIImagePickerController以允许用户选择要发布到服务的图片。然后我使用base64encoding将图像转换为字符串,如果我使用NSLog进行打印输出,那么该函数内部的一切都很好。但是,当我发布并回调NSString中的base64encoding值时,我得到一个空值。似乎ARC在UIView子类中的管理方式与UIViewController中的方式不同,因为此代码适用于viewController,而不是保留在我的子视图中。代码在下面......你可以提供的任何方向都会非常感激,我已经使用了这些值的属性,但是没有让ARC保留它。 .h文件

    @interface PostView: UIView
    {
        CGFloat animatedDistance;
        CGRect originalFrame;
        BOOL isShown;
        RESTURLDelagate *_connection;
        MBProgressHUD *HUD;
        NSMutableData *_data;
        NSData *imageData;
        UIAlertView *noConnection, *userSetup, *userExist, *accountAlertView, *confirmed, *login;
    }
    @property (weak, nonatomic) IBOutlet UIButton *postButton;
    @property (nonatomic, strong) IBOutlet UILabel *attachedLabel;
    @property (weak, nonatomic) IBOutlet UITextView *textView;
    @property (nonatomic, strong) IBOutlet UILabel *characterLimit;
    @property (nonatomic, strong) IBOutlet UIImageView *attachImage;
    @property (strong) NSString *encodedImage;
    - (NSString *)Base64Encode:(NSData *)data;
    - (IBAction)postAction:(id)sender;

    - (void)show;
    - (void)hide;

    @end

.m文件

    @implementation PostView

    @synthesize attachedLabel;
    @synthesize postButton;
    @synthesize textView;
    @synthesize characterLimit;
    @synthesize attachImage;
    @synthesize encodedImage;

    - (id)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            originalFrame = frame;
            NSArray *xib = [[NSBundle mainBundle] loadNibNamed:@"PostView" owner:self options:nil];
            PostView *view = [xib objectAtIndex:0];
            [view setBackgroundColor:[UIColor whiteColor]];
            [view setAlpha:0.7f];
            attachedLabel = [[UILabel alloc] initWithFrame:CGRectMake(204, 212, 56, 21)];
            attachedLabel.textColor = [UIColor blackColor];
            [attachedLabel setText:@"Attached"];
            [attachedLabel setHidden:YES];
            attachedLabel.backgroundColor = [UIColor clearColor];
            attachedLabel.font = [UIFont fontWithName:text_font_name size:12.0];
            characterLimit = [[UILabel alloc] initWithFrame:CGRectMake(246, 13, 50, 21)];
            [characterLimit setTextAlignment:NSTextAlignmentRight];
            characterLimit.textColor = [UIColor blackColor];
            characterLimit.backgroundColor = [UIColor clearColor];
            characterLimit.font = [UIFont fontWithName:text_font_name size:12.0];
            attachImage = [[UIImageView alloc] initWithFrame:CGRectMake(270, 208, 30, 30)];
            [attachImage setImage:[UIImage imageNamed:@"attachphoto30x30.png"]];
            [self.textView setDelegate:self];
            [self.textView setAlpha:0.7f];
            [self.textView setTextColor:[UIColor whiteColor]];
            [self.textView setBackgroundColor:[UIColor clearColor]];
            self.layer.cornerRadius = 10.0f;
            self.layer.masksToBounds = YES;
            [self addSubview:view];
            [self addSubview:characterLimit];
            [self addSubview:attachedLabel];
            [self addSubview:attachImage];
        }
        return self;
    }

    - (IBAction)openCamera:(id)sender
    {
        UIImagePickerController *controller = [[UIImagePickerController alloc] init];
        controller.delegate = self;
        [(ShamePostViewController *)[self.superview nextResponder] presentViewController:controller animated:YES                 
            completion:nil];
    }

    -(void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
    {
        [picker dismissViewControllerAnimated:YES completion:nil];
        UIImage *image = [info objectForKey: UIImagePickerControllerOriginalImage];
        //UIImage *scale = [image scaleToSize:CGSizeMake(320.0f, 548.0f)];
        imageData = [[NSData alloc] initWithData:UIImageJPEGRepresentation(image, 1)];
        encodedImage = [self Base64Encode:imageData];
        [attachedLabel setHidden:NO];
    }

    - (void)show
    {
        //prepare attachImage
        attachImage.userInteractionEnabled = YES;
        UITapGestureRecognizer *tapAttach = [[UITapGestureRecognizer alloc]
                                             initWithTarget:self action:@selector(openCamera:)];
        tapAttach.numberOfTapsRequired = 1;
        [self.attachImage addGestureRecognizer:tapAttach];


        isShown = YES;
        self.transform = CGAffineTransformMakeScale(0.1, 0.1);
        self.alpha = 0;
        [UIView beginAnimations:@"showAlert" context:nil];
        [self setBackgroundColor:[UIColor clearColor]];
        [UIView setAnimationDelegate:self];
        self.transform = CGAffineTransformMakeScale(1.1, 1.1);
        self.alpha = 1;
        [UIView commitAnimations];
    }

    - (void)hide
    {
        isShown = NO;
        [UIView beginAnimations:@"hideAlert" context:nil];
        [UIView setAnimationDelegate:self];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"hidePostView_Notification" object:nil];
        self.transform = CGAffineTransformMakeScale(0.1, 0.1);
        self.alpha = 0;
        [UIView commitAnimations];
    }

    - (void)toggle
    {
        if (isShown)
        {
            [self hide];
        } else
        {
            [self show];
        }
    }

    #pragma mark Animation delegate

    - (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
    {
        if ([animationID isEqualToString:@"showAlert"])
        {
            if (finished)
            {
                [UIView beginAnimations:nil context:nil];
                self.transform = CGAffineTransformMakeScale(1.0, 1.0);
                [UIView commitAnimations];
            }
        } else if ([animationID isEqualToString:@"hideAlert"])
        {
            if (finished)
            {
                self.transform = CGAffineTransformMakeScale(1.0, 1.0);
                self.frame = originalFrame;
            }
        }
    }
    #pragma mark BaseEncode64

    - (NSString *)Base64Encode:(NSData *)data
    {
        //Point to start of the data and set buffer sizes
        int inLength = [data length];
        int outLength = ((((inLength * 4)/3)/4)*4) + (((inLength * 4)/3)%4 ? 4 : 0);
        const char *inputBuffer = [data bytes];
        char *outputBuffer = malloc(outLength);
        outputBuffer[outLength] = 0;

        //64 digit code
        static char Encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

        //start the count
        int cycle = 0;
        int inpos = 0;
        int outpos = 0;
        char temp;

        //Pad the last to bytes, the outbuffer must always be a multiple of 4
        outputBuffer[outLength-1] = '=';
        outputBuffer[outLength-2] = '=';

        while (inpos < inLength){
            switch (cycle) {
                case 0:
                    outputBuffer[outpos++] = Encode[(inputBuffer[inpos]&0xFC)>>2];
                    cycle = 1;
                    break;
                case 1:
                    temp = (inputBuffer[inpos++]&0x03)<<4;
                    outputBuffer[outpos] = Encode[temp];
                    cycle = 2;
                    break;
                case 2:
                    outputBuffer[outpos++] = Encode[temp|(inputBuffer[inpos]&0xF0)>> 4];
                    temp = (inputBuffer[inpos++]&0x0F)<<2;
                    outputBuffer[outpos] = Encode[temp];
                    cycle = 3;
                    break;
                case 3:
                    outputBuffer[outpos++] = Encode[temp|(inputBuffer[inpos]&0xC0)>>6];
                    cycle = 4;
                    break;
                case 4:
                    outputBuffer[outpos++] = Encode[inputBuffer[inpos++]&0x3f];
                    cycle = 0;
                    break;
                    default:
                    cycle = 0;
                    break;
            }
        }
        NSString *pictemp = [NSString stringWithUTF8String:outputBuffer];
        free(outputBuffer);
        return pictemp;
    }

    #pragma Submit action for posting
    - (IBAction)postAction:(id)sender
    {
        if ([textView.text isEqualToString:@""])
        {
            UIAlertView *noText = [[UIAlertView alloc] initWithTitle:@"Missing Content" message:@"You must enter a message to post before submitting." delegate:self cancelButtonTitle:@"Dismiss" otherButtonTitles:nil, nil];
            [noText show];
        }else
            if ([[[NSUserDefaults standardUserDefaults] valueForKey:@"auth_id"] isEqualToString:@"1"])
            {
                _data = [[NSMutableData alloc] init];
                URLSingleton *urls = [URLSingleton sharedInstance];
                REQUESTBuilderDelagate *rbd = [[REQUESTBuilderDelagate alloc] init];
                NSString *blob_ind = [[NSString alloc] init];
                NSLog(@"%@", encodedImage);
                "STRING IS NULL HERE"
                if ([encodedImage length] > 0)
                {
                    blob_ind = @"1";
                }else
                    blob_ind = @"0";

                NSArray *keys = [[NSArray alloc] initWithObjects:@"token", @"postMsg", @"active", @"blob", nil];
                NSArray *values = [[NSArray alloc] initWithObjects:[[NSUserDefaults standardUserDefaults]         
                    valueForKey:@"session_token"], textView.text, @"1", blob_ind, nil];
                [rbd createJSONRequest:keys values:values];
                [rbd setPostURL:urls.postMessage];

                _connection = [[RESTURLDelagate alloc] initWithRequest:rbd.getPostURL delegate:self];
                [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
                [_connection setDescription:@"PVCPOSTMSG"];
                HUD = [MBProgressHUD showHUDAddedTo:self animated:YES];
                HUD.labelText = @"Posting...";
                [HUD setConnection:_connection];
                [_connection start];
                [postButton setEnabled:NO];
            }
            else
            {
                login = [[UIAlertView alloc] initWithTitle:@"Authentication Required" message:@"Please login before attempting to post!" delegate:self cancelButtonTitle:@"Dismiss" otherButtonTitles:nil, nil];
                [login show];
                [textView setText:@""];
                [characterLimit setText:@"0/160"];
            }

    }

    #pragma Post Image
    -(void)postImage:(NSString *)shameID
    {
        if ([[[NSUserDefaults standardUserDefaults] valueForKey:@"auth_id"] isEqualToString:@"1"])
        {
            URLSingleton *urls = [URLSingleton sharedInstance];
            REQUESTBuilderDelagate *rbd = [[REQUESTBuilderDelagate alloc] init];

            NSArray *keys = [[NSArray alloc] initWithObjects:@"token", @"encode64", @"active", @"SID", nil];
            NSArray *values = [[NSArray alloc] initWithObjects:[[NSUserDefaults standardUserDefaults] 
                    valueForKey:@"session_token"], encodedImage, @"1", SID, nil];

            [rbd createJSONRequest:keys values:values];
            [rbd setPostURL:urls.imagePost];

            _connection = [[RESTURLDelagate alloc] initWithRequest:rbd.getPostURL delegate:self];
            [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
            [_connection setDescription:@"PVCADDIMAGE"];
            HUD = [MBProgressHUD showHUDAddedTo:self animated:YES];
            HUD.labelText = @"Attaching Image...";
            [postButton setEnabled:NO];
            [HUD setConnection:_connection];
            [_connection start];
        }
    }

    @end

3 个答案:

答案 0 :(得分:0)

你只需要替换“encodedImage = [self Base64Encode:imageData];”使用给定的代码行,

[self setEncodedImage:[self Base64Encode:imageData]];

希望它能奏效:)

答案 1 :(得分:0)

您应该将属性更改为@property (nonatomic, strong) NSString *encodedImage;,并且应该将行encodedImage = [self Base64Encode:imageData];更改为self.encodedImage = [self Base64Encode:imageData];

修改

所以我看到了类似问题的答案(https://stackoverflow.com/a/13640603/2315974)所以我的最后一个想法是你应该移动

 UIImage *image = [info objectForKey: UIImagePickerControllerOriginalImage];
     //UIImage *scale = [image scaleToSize:CGSizeMake(320.0f, 548.0f)];
     imageData = [[NSData alloc] initWithData:UIImageJPEGRepresentation(image, 1)];
     encodedImage = [self Base64Encode:imageData];
    [attachedLabel setHidden:NO];

dismissViewControllerAnimated方法的完成块内。

答案 2 :(得分:0)

这不是一个答案,而是一个基于你的试用版,它运行正常。我在手机上的相机胶卷上添加了一个较小的图像,现在我在postAction方法中正确记录了字符串(我将log语句复制到方法的顶部,因为我没有对用户默认值做任何事情):< / p>

我在PostView中唯一改变的是postAction方法。这是:

- (IBAction)postAction:(id)sender
{

     NSLog(@"EncodedImage is :%@", encodedImage);


    if ([textView.text isEqualToString:@""])
    {
        UIAlertView *noText = [[UIAlertView alloc] initWithTitle:@"Missing Content" message:@"You must enter a message to post before submitting." delegate:self cancelButtonTitle:@"Dismiss" otherButtonTitles:nil, nil];
        [noText show];
    }else
        if ([[[NSUserDefaults standardUserDefaults] valueForKey:@"auth_id"] isEqualToString:@"1"])
        {
            _data = [[NSMutableData alloc] init];
            //URLSingleton *urls = [URLSingleton sharedInstance];
            //REQUESTBuilderDelagate *rbd = [[REQUESTBuilderDelagate alloc] init];
            NSString *blob_ind = [[NSString alloc] init];
            NSLog(@"EncodedImage is :%@", encodedImage);
            //"STRING IS NULL HERE"
            if ([encodedImage length] > 0)
            {
                blob_ind = @"1";
            }else
                blob_ind = @"0";

            NSArray *keys = [[NSArray alloc] initWithObjects:@"token", @"postMsg", @"active", @"blob", nil];
            NSArray *values = [[NSArray alloc] initWithObjects:[[NSUserDefaults standardUserDefaults]
                                                                valueForKey:@"session_token"], textView.text, @"1", blob_ind, nil];
            //[rbd createJSONRequest:keys values:values];
            //[rbd setPostURL:urls.postMessage];

            //_connection = [[RESTURLDelagate alloc] initWithRequest:rbd.getPostURL delegate:self];
            [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
            //[_connection setDescription:@"PVCPOSTMSG"];
            //HUD = [MBProgressHUD showHUDAddedTo:self animated:YES];
            //HUD.labelText = @"Posting...";
            //[HUD setConnection:_connection];
            //[_connection start];
            [postButton setEnabled:NO];
        }
        else
        {
            login = [[UIAlertView alloc] initWithTitle:@"Authentication Required" message:@"Please login before attempting to post!" delegate:self cancelButtonTitle:@"Dismiss" otherButtonTitles:nil, nil];
            [login show];
            [textView setText:@""];
            [characterLimit setText:@"0/160"];
        }

}

我在ViewController中使用此方法将PostView放在屏幕上:

-(IBAction)addPostView:(id)sender {
    PostView *postView = [[PostView alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:postView];
}

PostView的.h文件与你发布的相同,只不过我注释了几个ivars:

@interface PostView : UIView <UITextViewDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate>
{
    CGFloat animatedDistance;
    CGRect originalFrame;
    BOOL isShown;
    //RESTURLDelagate *_connection;
    //MBProgressHUD *HUD;
    NSMutableData *_data;
    NSData *imageData;
    UIAlertView *noConnection, *userSetup, *userExist, *accountAlertView, *confirmed, *login;
}
@property (weak, nonatomic) IBOutlet UIButton *postButton;
@property (nonatomic, strong) IBOutlet UILabel *attachedLabel;
@property (weak, nonatomic) IBOutlet UITextView *textView;
@property (nonatomic, strong) IBOutlet UILabel *characterLimit;
@property (nonatomic, strong) IBOutlet UIImageView *attachImage;
@property (strong) NSString *encodedImage;
- (NSString *)Base64Encode:(NSData *)data;
- (IBAction)postAction:(id)sender;

- (void)show;
- (void)hide;