Проблема IOS с доступом к свойствам класса

У меня есть представление, которое программно загружается как подпредставление. Представление имеет три свойства, определенные в .h и синтезированные в .m. Представление загружается путем создания объекта представления в родительском контроллере и последующего вызова его функции инициализации. В функции инициализации я устанавливаю ряд значений для соответствующих свойств. По какой-то причине я не могу получить доступ к свойствам вне функции инициализации. Моей первой мыслью было то, что свойства были определены неправильно, но после возни с их сильными и слабыми атрибутами ничего не изменилось.

UIView .h

#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import <Parse/Parse.h>

@protocol subViewDelegate
- (void)photoFromSubview:(NSInteger *)imageId;
- (void)downloadData;
@end

@interface ImageViewer : UIView

@property (nonatomic, assign) id <subViewDelegate> delegate;
//three properties
@property (nonatomic, copy) UIImage *mainImage;
@property (nonatomic, copy) UIViewController *parentView;
@property (nonatomic) NSInteger imageId;

- (void)removeImageViewer;
- (void)captureImage:(id)sender;
- (void)uploadPhoto:(id)sender;
- (UIImage *)addBackground;

- (ImageViewer *)loadImageIntoViewer:(UIViewController *)superView imageToLoad:(UIImage *)imageToLoad imageId:(NSInteger *)imageId;

@end

Соответствующие функции в UIViews .m

//implementation of the properties 
#import "ImageViewer.h"
#import "SpinnerView.h"

@implementation ImageViewer : UIView
{

}

@synthesize mainImage = _mainImage;
@synthesize parentView = _parentView;
@synthesize imageId = _imageId;

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

    }
    return self;
}

//initialization function
- (ImageViewer *)loadImageIntoViewer:(UIViewController *)superView imageToLoad:(UIImage *)imageToLoad imageId:(NSInteger *)imageId
{
    //create a new view with the same frame size as the superView
    ImageViewer *imageViewer = [[ImageViewer alloc] initWithFrame:superView.view.bounds];
    imageViewer.delegate = superView;

    //three properties assigning values 
    _mainImage = imageToLoad;
    _parentView = superView;
    _imageId = imageId;

    //if something's gone wrong, abort!
    if(!imageViewer)
    {
        return nil;
    }

    //add all components and functionalities to the program
    //when I use _mainImage bellow it works with the correct value 
    UIImageView *background = [[UIImageView alloc] initWithImage:[imageViewer addBackground]];
    background.alpha = 0.85;
    [imageViewer addSubview:background];
    [imageViewer addSubview:[imageViewer addImageToView:_mainImage superView:superView.view]];
    [imageViewer addSubview:[imageViewer addButtonToView:(superView.view.bounds.origin.x + 10.0) yPos:(superView.view.bounds.origin.x + 10.0) buttonAction:@selector(back:) buttonTitle:@"Back"]];
    [imageViewer addSubview:[imageViewer addButtonToView:(superView.view.bounds.origin.x + 10.0) yPos:((superView.view.center.y/2) + 270.0) buttonAction:@selector(captureImage:) buttonTitle:@"Camera"]];
    [imageViewer addSubview:[imageViewer addButtonToView:(superView.view.bounds.origin.x + 105.0) yPos:((superView.view.center.y/2) + 270.0) buttonAction:@selector(uploadPhoto:) buttonTitle:@"Upload"]];
    [superView.view addSubview:imageViewer];

    return imageViewer;
}

Приведенный выше код позволяет вам получить доступ к значениям, присвоенным _mainImage, _parentView и _imageId. Но когда я пытаюсь получить к ним доступ через приватную функцию, определенную в .m, я возвращаю инициализированное значение, как показано ниже.

- (void)uploadPhoto:(id)sender
{
   //These all return as empty or uninitialized
   NSLog(@"%@", _mainImage);
   NSLog(@"%d", _imageId);
}

Почему это? Я неправильно определяю свойства в .h или это потому, что self не ссылается на экземпляр ImageView, определенный в loadImageIntoViewer? Как я могу это исправить?


person ScottOBot    schedule 09.05.2013    source источник
comment
Один вопрос, если вы объявите их сильными вместо копии, будет ли это работать в частном методе?   -  person Radu    schedule 09.05.2013
comment
Я считаю, что вам не нужна копия UIViewController - вам нужна слабая ссылка на нее.   -  person Rok Jarc    schedule 09.05.2013


Ответы (1)


Некоторые мысли:

Во-первых, вам больше не нужно объявлять операторы @synthesize, если вы работаете с последней версией XCode. Компилятор автоматически вставит операторы синтеза и создаст переменные экземпляра, добавив в конце символ подчеркивания (как вы это сделали).

Во-вторых, когда вы говорите, что «не можете получить доступ к свойствам вне функции инициализации», вы имеете в виду, что когда вы пытаетесь получить доступ к свойствам, вы получаете плохой доступ или они просто возвращают ноль? Я не уверен, имеете ли вы в виду то, что говорите, потому что, глядя на ваш текущий метод инициализации, вы в настоящее время вообще не обращаетесь к свойствам, а только к их переменным экземпляра.

Я думаю, вы можете перепутать переменные экземпляра и свойства. Свойство в Objective-C выглядит так:

NSLog(@"%@", self.mainImage);

... структура вашего приложения меня тоже немного сбивает с толку. Ваш метод инициализации является методом экземпляра, а не класса, поэтому вы создаете один ImageViewer только для того, чтобы затем он создал другой ImageViewer. Я предлагаю вам попробовать создать настоящий метод инициализации, который вызывает initWithFrame. Я думаю, может быть, вам будет полезно просмотреть вступительную документацию Apple по Objective-C, поскольку я не думаю, что структура вашего приложения поможет вам отладить проблему.

person lxt    schedule 09.05.2013
comment
Я прочитал документацию для UIView. Я точно понимаю, что вы имеете в виду, говоря о путанице между классом и экземпляром. Я не знал, что initWithFrame был методом инициализации для UIView. По сути, я скопировал код из загружаемого изображения в метод initWithFrame. Теперь у меня есть пара вопросов, в документации сказано, что метод initWithFrame может быть настроен или переделан, могу ли я добавить свои параметры ow в метод initWithFrame? Также вызывается ли метод initWithFrame, когда я добавляю представление из моего основного контроллера представления с помощью addSubview? @lxt - person ScottOBot; 09.05.2013