Несколько строк кода, которые ударяют мой разум (или NSString »из прицела« Дилемма .. снова)

StackOverflow https://stackoverflow.com/questions/3590372

  •  01-10-2019
  •  | 
  •  

Вопрос

Я полностью запутался с этим маленьким «вне охвата». Так вот какой-то код, чтобы описать мою ситуацию:

Простое приложение на основе просмотра iPhone.

Просмотр заголовка контроллера:

#import <UIKit/UIKit.h>

@interface global_nsstring_testViewController : UIViewController {
 UIImageView* image_view;
 NSString*  image_name;
}

@property (nonatomic,retain) UIImageView* image_view;
@property (nonatomic,retain) NSString*  image_name;

- (void) fadeView:(UIImageView*)View andThenChangeImageTo:(NSString*)Name;
- (void) switchImageAfterFade;

@end

Просмотр контроллера .m:

#import "global_nsstring_testViewController.h"
@implementation global_nsstring_testViewController
@synthesize image_view, image_name;

- (void) viewDidLoad {
 image_view = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"image1.png" ofType:nil]]];

//  ## Block 1 ## 
// NSString* name = @"image2.png";
// [self fadeView:image_view andThenChangeImageTo:name];

// ## Block 2 ##
// NSString* name = [NSString stringWithFormat:@"image%d.png",2];
// [self fadeView:image_view andThenChangeImageTo:name];

 [self.view addSubview:image_view];
 [super viewDidLoad];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
//  ## Block 3 ##
// NSString* name = @"image2.png";
// [self fadeView:image_view andThenChangeImageTo:name];

//  ## Block 4 ##
    NSString* name = [NSString stringWithFormat:@"image%d.png",2];
    [self fadeView:image_view andThenChangeImageTo:name];
}

- (void) fadeView:(UIImageView*)View andThenChangeImageTo:(NSString*)Name {
 image_name = Name;
 image_view = View; // ## Point 1 ##

 [UIView beginAnimations:nil context:nil];
 [UIView setAnimationDuration:1];
 [UIView setAnimationDelegate:self];
 [UIView setAnimationDidStopSelector:@selector(switchImageAfterFade)];
 View.alpha = 0.3;
 [UIView commitAnimations];
}

- (void) switchImageAfterFade {
 UIImage* image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:image_name ofType:nil]]; // ## Point 2 ##
 [image_view setImage:image];
}

- (void) dealloc {
 [image_view removeFromSuperview];
 [image_view release];
    [super dealloc];
}

@end

С незаметным #block 4 # я получаю сообщение «вне прицела» из отладчика на Image_Name var в #point 1 #. И поэтому я получаю Exc_bad_Access на #point 2 #.

Однако с незаметным #block 3 # или #block 1 # вместо #block 4 # все работает нормально, поэтому я полагаю, что это все о NSSTRING ...

Я пытался использовать NSMutableString, но без каких-либо успехов.

Так что, если кто-то может сказать мне, что я делаю не так или как это исправить, я бы очень ценю.

Еще одна странная вещь, которую я не получаю:

Если восполнить #block 2 # и не использовать какие-либо точки останова, он не будет сбиться, но изображение исчезнет. Но если я установлю точку останова на #point 2 #, он будет крах с Exc_bad_Access через один шаг.

Xcode версия: 3.2.3

Это было полезно?

Решение

Прежде всего, «вне охвата» в отладчике просто означает, что отладчик не может понять, как отобразить переменную. Это по сути бессмысленно. Вы можете распечатать значение, нажав на консоль (который имеет «GDB>» в нем) и набрав

po image_name

Во-вторых, вы не используете заселенцы правильно. У вас есть @ недвижимость для ваших двух переменных, но вы не с использованием их. Когда вы делаете

variable = value;

Это просто настройка переменной - никаких методов свойств не вызывается. Однако,

self.variable = value;

Позвонит на сетте о недвижимости, поскольку у вас есть «нетомический, сохранить», сохранит вашу переменную, и все будет набухать.

В этом случае вы делаете

image_name = Name;

где вы хотите сделать

self.image_name = Name;

или (как предлагает TOB)

image_name = [Name retain];

Это очень распространенное, когда вы начинаете делать объективные кодирование C, что вы путаете два способа установить переменную в классе, и жизненно важно, чтобы вы получили разницу. Ваши свойства не вызываются, когда вы не используете пример точка Переменная.

По совпадению, многие люди также склонны путать это еще больше, делая такие вещи, как

self.image_name = [Name retain];

Это абсолютно неверно. Вы получите утечку «имя» каждый раз, когда вы устанавливаете Image_Name, из-за двойного сохранения (один раз для @Property (неавтоматический, удерживать) в вашем сеттере, и один раз для [Name retain]).

Другие советы

Блок 4 использует удобный инициализатор, поэтому вы должны использовать [[NSString stringWithFormat:@"image%d.png",2] retain] Или это будет автозадаться. Не забудьте освободить его после назначения self.image_name = name

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top