【发布时间】:2011-10-02 10:25:44
【问题描述】:
我有一个带有三个 ViewController(A、B 和 C)的 UITabBarController。在 ViewControllerB 我有一个 UIScrollView。 UIScrollView 由我的 PhotoViewController 的几个实例组成。这些 PhotoViewController 对象是从 ViewControllerA 调用的,而不是从它们所在的 ViewController B 调用的。
PhotoViewController 实例有一个 UIImage 和一个两个按钮。起初,当我单击其中一个 PhotoViewController 实例中的按钮时,我收到了“线程 1:程序接收信号:“EXC_BAD_ACCESS”错误。在stackoverflow上环顾四周,只要出现内存管理问题,似乎就会出现错误。
由于我是通过在 ViewControllerA 中调用的方法在循环中创建 PhotoViewController 对象并释放这些对象,我认为当我切换到 ViewControllerB 时它们已经被释放 - 因此存在内存问题。
但这只是我的猜测。你能告诉我是否应该停止在循环代码中释放 PhotoViewController 对象吗?因为这就是我所做的(只是评论了那条线)并且程序“运行良好”。但是,我仍然不确定这是否是处理它的正确方法以及它是否会导致未知的内存管理问题。
这是我的一些代码:
ViewControllerA.m
//在ViewControllerB中创建相册,相册中的照片是PhotoViewController对象
-(IBAction)showAlbum:(UIButton *)sender
{
//Go goes here to get an album and display it in the UIScrollView
albumID = @"ALBUM_ID";
NSString* graphUrl = [NSString stringWithFormat:@"%@/photos?limit=10", albumID];
[_facebook requestWithGraphPath:graphUrl andDelegate:self];
}
...
- (void)request:(FBRequest *)request didLoad:(id)result {
//Code for array of photos
NSLog(@"%@",result);
NSString *requestType = [request.url stringByReplacingOccurrencesOfString:@"https://graph.facebook.com/" withString:@""];
if ([requestType isEqualToString:[NSString stringWithFormat:@"%@/photos?limit=10", albumID]]){
NSArray *photoAlbumArray=(NSArray*)[result valueForKey:@"data"];
[self.label setText:[NSString stringWithFormat:@"%i", [photoAlbumArray count]]];
for(UIViewController *controller in self.tabBarController.viewControllers)
{
if([controller isKindOfClass:[ViewControllerB class]])
{
ViewControllerB *mtbvc = (ViewControllerB *)controller;
[mtbvc setArray:photoAlbumArray];
self.tabBarController.selectedIndex = 1;//switch over to the second view to see if it worked
}
}
}
...
@end
ViewControllerB.m
//我创建 PhotoViewController 对象的循环
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
arrayCount = [array count];
scroller.delegate=self;
scroller.pagingEnabled=YES;
scroller.directionalLockEnabled=YES;
scroller.showsHorizontalScrollIndicator=NO;
scroller.showsVerticalScrollIndicator=NO;
//should have an array of photo objects and the number of objects, correct?
scrollWidth = 0;
scroller.contentSize=CGSizeMake(arrayCount*scroller.frame.size.width, scroller.frame.size.height);
for (int i = 0; i < arrayCount;i++) {
PhotoViewController *pvc = [[PhotoViewController alloc] initWithNibName:@"PhotoViewController" bundle:nil];
UIImageView *scrollImageView = [[UIImageView alloc] initWithFrame:CGRectOffset(scroller.bounds, scrollWidth, 0)];
CGRect rect = scrollImageView.frame;
pvc.view.frame = rect;
[pvc view];
pvc.label.textColor = [UIColor whiteColor];
id individualPhoto = [array objectAtIndex:i];
NSLog(@"%@",individualPhoto);
NSArray *keys=[individualPhoto allKeys];
NSLog(@"%@",keys);
NSString *imageURL=[individualPhoto objectForKey:@"source"];
//here you can use this imageURL to get image-data and display it in imageView
NSURL *url = [NSURL URLWithString:imageURL];
NSData *data = [NSData dataWithContentsOfURL:url];
pvc.imageView.image = [[UIImage alloc] initWithData:data];
pvc.label.text = [individualPhoto objectForKey:@"id"];
//check to make sure the proper URL was passed
//I have an imageView next to the UIScrollView to test whether that works - it does.
[scroller addSubview:pvc.view];
[scrollImageView release];
//[pvc release];
scrollWidth += scroller.frame.size.width;
}
if (arrayCount > 3) {
pageControl.numberOfPages=3;
} else {
pageControl.numberOfPages=arrayCount;
}
pageControl.currentPage=0;
//[self.view addSubview:scroller];
}
PhotoViewController.m
#import "PhotoViewController.h"
@implementation PhotoViewController
@synthesize label, imageView;
-(IBAction)likeButton:(UIButton *)sender
{
//code goes here
for(UIViewController *controller in self.tabBarController.viewControllers)
{
if([controller isKindOfClass:[DemoAppViewController class]])
{
DemoAppViewController *davc = (DemoAppViewController *)controller;
[davc likePicture:self.label.text];
}
}
self.tabBarController.selectedIndex = 0;//switch over to the third view to see if it worked
}
-(IBAction)skipButton:(UIButton *)sender
{
//code goes here
}
-(IBAction)likeCommentButton:(UIButton *)sender
{
//code goes here
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
@end
PhotoViewController.h
#import <UIKit/UIKit.h>
#import "DemoAppViewController.h"
#import "MyTabBarViewController.h"
@interface PhotoViewController : UIViewController {
IBOutlet UILabel *label;
IBOutlet UIImageView *imageView;
UIButton *likeButton;
UIButton *skipButton;
UIButton *likeCommentButton;
}
@property (nonatomic, retain) UILabel *label;
@property (nonatomic, retain) UIImageView *imageView;
-(IBAction)likeButton:(UIButton *)sender;
-(IBAction)skipButton:(UIButton *)sender;
-(IBAction)likeCommentButton:(UIButton *)sender;
@end
【问题讨论】:
标签: iphone objective-c object memory-management uiviewcontroller