我有一个基于UINavigationController
的故事板的应用程序。
我有三个视图A,B,C。当用户点击相机按钮时,我在View A中启动相机,在成功点击图像并获得该图像后,我正在调用segue转到B,这是一个PUSH segue。在视图B中,我正在显示带有处理图像选项的图像。当用户选择处理它时,用PUSH segue查看C.现在我想要的是处理后的图像应该发送回到视图B,我将在那里显示处理过的图像。
问题是当我使用指向B(delegate
)app崩溃的指针将图像从C传递回B时。
代码如下
在视图B中将图像传递给视图C:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:@"Segue1"])
{
// Get reference to the destination view controller
CViewController *vc = [segue destinationViewController];
// Pass any objects to the view controller here, like...
vc.imageChosen = imageChosen;
vc.delegate = self;
}
}
delegate
在CViewController
中声明如下:
@property (nonatomic,retain) id delegate;
在视图控制器C中返回图像,我正在执行以下操作
-(IBAction)actionBack
{
BViewController *vc = (BViewController *)delegate;
vc.imageChosen = imageCropped;
[self.navigationController popViewControllerAnimated:TRUE];
}
actionBack
是附加到视图C上的后退按钮的选择器
应用程序在EXC_BAD_ACCESS
中的一行BViewController.h
上崩溃,如下所示
@property (nonatomic,retain) UIImage *imageChosen;
我已检查imageCropped
包含我尝试保存到图库的有效数据imageCropped
是CViewController
中的属性,后面有声明
@property (nonatomic,retain) UIImage *imageCropped;
我不明白为什么会崩溃,我们将不胜感激。
答案 0 :(得分:1)
有几点想法:
您建议您在B中定义EXC_BAD_ACCESS
的行中获得imageChosen
。
@property (nonatomic,retain) UIImage *imageChosen;
这不太可能。您没有在定义属性的行中获得EXC_BAD_ACCESS
,而是在尝试使用该属性或其关联的ivar的行。你可能会在多个地方引用它,所以你真的应该找出有问题的代码行。您应该turn on exception breakpoints或者仔细查看堆栈跟踪以准确识别异常发生的位置,而不是我们猜测这个EXC_BAD_ACCESS
发生在哪一行。
由于你在手动保留和释放代码中乱七八糟,你真的应该:
通过静态分析器运行代码(Xcode“产品”菜单上的“分析”),并确保修复所有警告。
暂时turn on zombies,以便您可以正确识别任何过度发布的商品。
您没有告诉我们您如何定义delegate
属性。我只是提到这一点,因为您设置了delegate
属性,但C继续使用delegate
实例变量(现代约定就是您的ivars应该有前导下划线,例如_delegate
)。你可以按照你在代码片段中建议的方式进行操作,但如果没有完全正确地完成,它会受到一系列特定条件的影响,这些条件会导致你描述的崩溃。
就个人而言,我建议(a)你确保你没有为delegate
明确宣布ivar(只需定义属性并让ivar合成); (b)排除任何明确的@synthesize
陈述(而是让它自动合成); (c)尽可能使用存取方法。
与您的崩溃无关,但您在这里有一个保留周期。引用回B的C中的delegate
应该是assign
,而不是retain
(或者如果您使用的是ARC,weak
而不是strong
。您将按照当前编写的方式保留一个保留周期,因此您将泄漏。
另外,作为一个好的风格,你也应该使用协议,但这并不重要。
答案 1 :(得分:0)
我最好在委托中使用某种方法为其提供图像。
这样的事情:
if (_delegate && [_delegate respondsToSelector:@selector(passImage:)])
{
[_delegate passImage:imageCropped];
}
并在代表本身:
- (void)passImage:(UIImage *)img
{
// do something
}
希望它能帮到你。