我对这个小的“超出范围”的事情感到困惑。 所以这里有一些代码来描述我的情况:
简单的基于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#,我会在#Point 1#的image_name var上从调试器获得“超出范围”消息。因此,我在#Point 2#。
获得EXC_BAD_ACCESS然而,使用未注释的#Block 3#或#Block 1#而不是#Block 4#一切正常,所以我想这都是关于NSString ......
我尝试过使用NSMutableString,但也没有任何成功。
所以如果有人能告诉我,我做错了什么或如何解决它,我将非常感激。
另一个奇怪的事情,我没有得到:
如果取消注释#Block 2#并且不使用任何断点,它将不会崩溃,但图像将消失。但是如果我在#Point 2#设置一个断点,只需一步就会崩溃EXC_BAD_ACCESS。
xCode版本:3.2.3
答案 0 :(得分:1)
首先,调试器中的“超出范围”仅意味着调试器无法弄清楚如何显示变量。这基本上毫无意义。您可以通过单击控制台(其中包含“gdb&gt;”)并键入
来打印该值po image_name
其次,您没有正确使用setter。你的两个变量有@ property属性,但你不是使用它们。当你这样做
variable = value;
它只是设置变量 - 没有调用属性方法。然而,
self.variable = value;
会调用属性setter,因为你已经“unatomic,retain”会保留你的变量,而且所有变量都会膨胀。
在这种情况下,你正在做
image_name = Name;
你想去哪里
self.image_name = Name;
或(如建议的那样)
image_name = [Name retain];
当你开始进行Objective-C编码时,你会混淆两种在类中设置变量的方法,这是很常见的事情,而且你获得差异至关重要。如果不使用实例 dot 变量,则不会调用您的属性。
巧合的是,很多人也倾向于通过做像
这样的事情来混淆这一点self.image_name = [Name retain];
这绝对不正确。每次设置image_name时最终都会泄漏“名称”,因为你的setter中有一次双重保留(一次为@property(非原子,保留),一次为[Name retain]
)
答案 1 :(得分:0)
第4块使用便利初始化程序,因此您应该使用[[NSString stringWithFormat:@"image%d.png",2] retain]
,否则它将自动释放。
在使用self.image_name = name