我在我的应用中使用自定义单元格。当用户点击表格行时,会出现一个自定义单元格:
#import "SonaraamatuKontroller.h"
#import "TolkegaLahter.h"
//Lahtris kasutatava teksti fondi suurus
#define FONT_SIZE 14.0f
//Tabelilahtri laius
#define CELL_CONTENT_WIDTH 320.0f
//Tabeli sisu äärise kaugus lahtri servadest
#define CELL_CONTENT_MARGIN 5.0f
@implementation SonaraamatuKontroller
@synthesize sonaraamatuSisukord=sonaraamatuSisukord;
@synthesize sonaraamatuTabel;
@synthesize valitudLahtriIndexPath;
@synthesize tolkegaLahter;
@synthesize audioPleier;
@synthesize sonaraamatuFailinimi;
@synthesize sonaraamatuNavribaNimi;
- (void)viewDidLoad {
[super viewDidLoad];
NSString *error;
NSPropertyListFormat format;
NSString *localizedPath = [[NSBundle mainBundle] pathForResource:sonaraamatuFailinimi ofType:@"plist"];
NSData *plistData = [NSData dataWithContentsOfFile:localizedPath];
NSArray *sisukordData = [NSPropertyListSerialization propertyListFromData:plistData
mutabilityOption:NSPropertyListImmutable
format:&format
errorDescription:&error];
if (sisukordData) {
self.sonaraamatuSisukord = [NSMutableArray arrayWithCapacity:[sonaraamatuSisukord count]];
for (NSDictionary *sisukordDictionary in sisukordData) {
[self.sonaraamatuSisukord addObject:sisukordDictionary];
}
}
self.navigationItem.title=sonaraamatuNavribaNimi;
}
- (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.
}
- (void)viewDidUnload {
//Teise vaatesse liikumisel pannakse audiopleier seisma
[audioPleier stop];
// Release anything that can be recreated in viewDidLoad or on demand.
// e.g. self.myOutlet = nil;
}
#pragma mark -
#pragma mark UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
//Loeme tabeli sektsioonide arvu - kuna praegusel juhul on sisukorras ainult üks liige (sõnaraamat "Item 0"), siis on ka sektsioone üks
return [sonaraamatuSisukord count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
//Loeme vastavas sektsioonis asuvate ridade arvu
NSMutableArray *sisukordItems = [[sonaraamatuSisukord objectAtIndex:section] objectForKey:@"Items"];
return [sisukordItems count];
}
- (CGFloat) tableView : (UITableView *) tableView
heightForRowAtIndexPath: (NSIndexPath *) indexPath {
if(valitudLahtriIndexPath != nil
&& [valitudLahtriIndexPath isEqual:indexPath] )
return 95;
NSMutableArray *sisukordItems = [[sonaraamatuSisukord objectAtIndex:indexPath.section] objectForKey:@"Items"];
NSDictionary *sisukordItem = [sisukordItems objectAtIndex:indexPath.row];
NSString *text = [sisukordItem objectForKey:@"Valjend"];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
CGFloat height = MAX(size.height, 25.0f);
return height + (CELL_CONTENT_MARGIN * 2);
}
#pragma mark -
#pragma mark UITableViewDelegate
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if((valitudLahtriIndexPath != nil)
&& [valitudLahtriIndexPath isEqual:indexPath]
)
{ //NSLog (@"ValitudPath: %@", valitudLahtriIndexPath);
static NSString *TolkegaLahtriTunnus = @"TolkegaLahter";
TolkegaLahter *cell = (TolkegaLahter *)[tableView dequeueReusableCellWithIdentifier:TolkegaLahtriTunnus];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:@"TolkegaLahter" owner:self options:nil];
cell = tolkegaLahter;
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
//Lisame gradiendi:
CAGradientLayer *gradient = [CAGradientLayer layer];
[gradient setCornerRadius:9.0f];
//[gradient setMasksToBounds:YES];
//[gradient setBorderWidth:0.8f];
//[gradient setBorderColor:[[UIColor darkGrayColor] CGColor]];
gradient.frame = cell.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithRed:0.122 green:0.2 blue:1 alpha:0.95] CGColor], (id)[[UIColor colorWithRed:0.041 green:0.1 blue:0.33 alpha:0.95] CGColor],(id)[[UIColor colorWithRed:0.122 green:0.2 blue:1 alpha:0.95] CGColor], nil];
gradient.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],[NSNumber numberWithFloat:0.48],[NSNumber numberWithFloat:1.0], nil];
[cell.layer insertSublayer:gradient atIndex:0];
}
NSMutableArray *sisukordItems = [[sonaraamatuSisukord objectAtIndex:indexPath.section] objectForKey:@"Items"];
NSDictionary *sisukordItem = [sisukordItems objectAtIndex:indexPath.row];
cell.valjend.text=[sisukordItem objectForKey:@"Valjend"];
cell.tolge.text=[sisukordItem objectForKey:@"Tolge"];
[sonaraamatuTabel scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionNone animated:YES];
self.tolkegaLahter = nil;
return cell;
}
static NSString *CellIdentifier = @"Cell";
//Loome lahtrisse labeli
UILabel *label = nil;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
//Esialgu on label tühi (asub punktis 0,0 ning on suurusega 0,0)
label = [[UILabel alloc] initWithFrame:CGRectZero];
//Määrame reavahetuse stiili
[label setLineBreakMode:UILineBreakModeWordWrap];
//Minimaalne fondi suurus on ülal defineeritud konstant
[label setMinimumFontSize:FONT_SIZE];
//Esialgu on ridade arv 0
[label setNumberOfLines:0];
//Määrame fondi. Selle suuruseks on ülal defineeritud konstant
[label setFont:[UIFont systemFontOfSize:FONT_SIZE]];
[label setTag:1];
//Lisame labelile piirid, et programmeerimise käigus oleks paremini näha, kuhu see lahtris paigutub
//[[label layer] setBorderWidth:2.0f];
[[cell contentView] addSubview:label];
[label release];
}
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
cell.selectedBackgroundView=[[[UIView alloc] init] autorelease];
cell.selectedBackgroundView.backgroundColor=[UIColor colorWithRed:0.537 green:0.18 blue:0.122 alpha:1.0];
//Loome andmemassiivi sisukord objektidest (tuntakse ära võtme "Items" abil) andmemassiivi sisukordItems
NSMutableArray *sisukordItems = [[sonaraamatuSisukord objectAtIndex:indexPath.section] objectForKey:@"Items"];
//Loome andmemassiivi sisukordItems objektidest sõnaraamatud sisukordItem
NSDictionary *sisukordItem = [sisukordItems objectAtIndex:indexPath.row];
//Igas lahtris kuvatakse sellele vastavas sõnaraamatus sisalduva objekti "Valjend" väärtus
NSString *text = [sisukordItem objectForKey:@"Valjend"];
//Sarnaselt lahtri kõrguse arvutamisele heightForRowAtIndexPath meetodis arvutame ka labeli
//kõrguse (sellele ei liideta ääriste kaugusi)
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
//Hangime labeli juhul kui see on nil (ja tegu ei ole vaate esialgse initsieerimisega ehk lahter ei ole nil)
if (!label)
label = (UILabel*)[cell viewWithTag:1];
//Seame labeli teksti
[label setText:text];
//Seame labeli piirjooned
[label setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), MAX(size.height, 25.0f))];
label.textColor=[UIColor blackColor];
label.font=[UIFont systemFontOfSize:14];
label.backgroundColor=[UIColor clearColor];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.valitudLahtriIndexPath = indexPath;
if(valitudLahtriIndexPath != nil //Kui see väärtus on tõene,
&& [valitudLahtriIndexPath isEqual:indexPath]) {
[self.sonaraamatuTabel reloadData];
NSMutableArray *sisukordItems = [[sonaraamatuSisukord objectAtIndex:indexPath.section] objectForKey:@"Items"];
NSDictionary *sisukordItem = [sisukordItems objectAtIndex:indexPath.row];
NSString*heliFailinimi=[sisukordItem objectForKey:@"HeliFailinimi"];
NSError *setCategoryError = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError];
NSString *taustaHeliPath = [[NSBundle mainBundle] pathForResource:heliFailinimi ofType:@"m4a"];
[audioPleier stop];
NSURL *taustaHeliURL = [NSURL fileURLWithPath:taustaHeliPath];
NSError *error;
audioPleier = [[AVAudioPlayer alloc] initWithContentsOfURL:taustaHeliURL error:&error];
[audioPleier setDelegate:self]; // We need this so we can restart after interruptions
[audioPleier play];
}
}
- (void)viewWillAppear:(BOOL)animated
{
NSIndexPath*selection = [self.sonaraamatuTabel indexPathForSelectedRow];
if (selection)
[self.sonaraamatuTabel deselectRowAtIndexPath:selection animated:YES];
[self.sonaraamatuTabel reloadData];
}
- (void)dealloc {
[valitudLahtriIndexPath release];
[sonaraamatuSisukord release], sonaraamatuSisukord=nil;
[audioPleier release];
[sonaraamatuFailinimi release];
[sonaraamatuNavribaNimi release];
[super dealloc];
}
@end
点按250次后,应用程序崩溃,我收到消息:
由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'无法在包中加载NIB:'NSBundle(已加载)',名称为“TolkegaLahter”
这种行为可能是什么原因?某处有内存泄漏?
修改
这是关于AVAudioPlayer,它一次又一次地创建,但没有发布。 所以,我换了
audioPleier = [[AVAudioPlayer alloc] initWithContentsOfURL:taustaHeliURL error:&error];
与
AVAudioPlayer*ajutineAudioPleier = [[AVAudioPlayer alloc] initWithContentsOfURL:taustaHeliURL error:&error];
self.audioPleier=ajutineAudioPleier;
[ajutineAudioPleier release];
答案 0 :(得分:1)
尝试替换
[[NSBundle mainBundle] loadNibNamed:@"TolkegaLahter" owner:self options:nil];
cell = tolkegaLahter;
到
cell = [[[TolkegaLahter alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier: TolkegaLahtriTunnus] autorelease];
self.tolkegaLahter = [[[NSBundle mainBundle] loadNibNamed:@"TolkegaLahter" owner:self options:nil] lastObject];
cell = self.tolkegaLahter;
答案 1 :(得分:1)
你问题中的代码是cellForRowAtIndexPath方法吗?从您的问题中不清楚此代码的行踪或执行时间。
如果是(或者,对于其中一些,即使它不是),它有几个问题:
如果您反复从笔尖加载,您可能还想查看UINib
。
修改强>
在查看完整代码之后,我认为问题出在你的音频播放器上,每次选择单元格时都会创建并配置一个新的代码,这就是泄漏。
您应该只在viewDidLoad上设置音频播放器,并在选择单元格时告诉它播放特定的声音。