将导致“程序接收信号:‘SIGKILL’。”
我有一个 UITableView,我使用以下代码扩展/缩小单元格。 我保存最后 2 个 indexPaths 以对其执行 reloadRowsAtIndexPaths:
。
现在,我在第 0 部分的标题中添加了一个 UISearchBar
。如果我点击 searchBar,KeyBoard 就会显示在 UITableView 的顶部 - 到目前为止一切顺利。
但我希望用户能够触摸单元格并禁用键盘。为此,我测试搜索框是否是 -tableView:didSelectRowAtIndexPath:
内的第一个响应者,
但这样做会导致标记 1、2、3 的行中出现“SIGKILL”,
我真的不明白为什么
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
Article *article = [articles objectAtIndex:indexPath.row];
ArticleCell *cell = (ArticleCell*)[self.tableView dequeueReusableCellWithIdentifier:@"articelcell"];
if (cell == nil)
{
cell = [[[NSBundle mainBundle] loadNibNamed:@"ExtendibleCell" owner:self options:nil] objectAtIndex:0];
}
//....
cell.articleName.text = [NSString stringWithFormat:@"%@",article.name ];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if ([searchBar isFirstResponder]) {
[searchBar resignFirstResponder];
}
[orderTableDelegate receiveSelectedArticleName:[[articles objectAtIndex:indexPath.row] name]];
firstSelected = lastSelected;
lastSelected = indexPath;
if (lastSelected == firstSelected && firstSelected != nil) {
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:lastSelected] withRowAnimation:CELL_ANIMATION]; //1
lastSelected = nil;
firstSelected = nil;
return;
}
if (lastSelected != nil) {
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:CELL_ANIMATION];//2
}
if (firstSelected != nil) {
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:firstSelected] withRowAnimation:CELL_ANIMATION];//3
}
}
-(UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
if (section ==0) {
if (searchBar == nil) {
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
[searchBar setShowsBookmarkButton:YES];
[searchBar setKeyboardType:UIKeyboardTypeAlphabet];
[searchBar setBarStyle:UIBarStyleBlack];
[searchBar setShowsCancelButton:YES];
[searchBar setDelegate:self];
}
return searchBar;
}
return nil;
}
-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([indexPath isEqual:lastSelected] && lastSelected!=firstSelected) {
return [[(Article *)[articles objectAtIndex:indexPath.row] sizesAndPrices] count]*PACKAGESIZE_PRICE_BUTTON_HEIGHT +30;
}
return 40.0;
}
编辑 我清理了 -tableView:didSelectRowAtIndexPath:
的代码,但问题仍然存在
@property(nonatomic,retain) NSIndexPath *firstSelected;
@property(nonatomic,retain) NSIndexPath *lastSelected;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[orderTableDelegate receiveSelectedArticleName:[[articles objectAtIndex:indexPath.row] name]];
self.firstSelected = nil;
self.firstSelected = self.lastSelected;
self.lastSelected = nil;
self.lastSelected = [indexPath retain];
if (self.firstSelected == self.lastSelected) {
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:self.firstSelected] withRowAnimation:CELL_ANIMATION];
[self.firstSelected release];
[self.lastSelected release];
self.firstSelected = nil ;
self.lastSelected = nil ;
} else {
if (self.firstSelected != nil) {
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:self.firstSelected] withRowAnimation:CELL_ANIMATION];
}
if (self.lastSelected != nil) {
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:self.lastSelected] withRowAnimation:CELL_ANIMATION];
}
}
if ([searchBar isFirstResponder]) {
[searchBar resignFirstResponder];
}
}
I have a UITableView, where I extend/shrink the cells with the following code.
I save the last 2 indexPaths to perform a reloadRowsAtIndexPaths:
on it.
Now I added a UISearchBar
to the header for section 0. If I tab the searchBar, a KeyBoard is displayed on top of the UITableView — so far so good.
But I want the user to be able to touch the Cells and disable the KeyBoard. To do so, I test if the searchbox is the first responder inside the -tableView:didSelectRowAtIndexPath:
But doing so will lead to a "SIGKILL" in one of the rows marks 1, 2, 3
I really don't understand why
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
Article *article = [articles objectAtIndex:indexPath.row];
ArticleCell *cell = (ArticleCell*)[self.tableView dequeueReusableCellWithIdentifier:@"articelcell"];
if (cell == nil)
{
cell = [[[NSBundle mainBundle] loadNibNamed:@"ExtendibleCell" owner:self options:nil] objectAtIndex:0];
}
//....
cell.articleName.text = [NSString stringWithFormat:@"%@",article.name ];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if ([searchBar isFirstResponder]) {
[searchBar resignFirstResponder];
}
[orderTableDelegate receiveSelectedArticleName:[[articles objectAtIndex:indexPath.row] name]];
firstSelected = lastSelected;
lastSelected = indexPath;
if (lastSelected == firstSelected && firstSelected != nil) {
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:lastSelected] withRowAnimation:CELL_ANIMATION]; //1
lastSelected = nil;
firstSelected = nil;
return;
}
if (lastSelected != nil) {
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:CELL_ANIMATION];//2
}
if (firstSelected != nil) {
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:firstSelected] withRowAnimation:CELL_ANIMATION];//3
}
}
-(UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
if (section ==0) {
if (searchBar == nil) {
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
[searchBar setShowsBookmarkButton:YES];
[searchBar setKeyboardType:UIKeyboardTypeAlphabet];
[searchBar setBarStyle:UIBarStyleBlack];
[searchBar setShowsCancelButton:YES];
[searchBar setDelegate:self];
}
return searchBar;
}
return nil;
}
-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([indexPath isEqual:lastSelected] && lastSelected!=firstSelected) {
return [[(Article *)[articles objectAtIndex:indexPath.row] sizesAndPrices] count]*PACKAGESIZE_PRICE_BUTTON_HEIGHT +30;
}
return 40.0;
}
edit
I cleaned up my code for -tableView:didSelectRowAtIndexPath:
, but the problem stays the same
@property(nonatomic,retain) NSIndexPath *firstSelected;
@property(nonatomic,retain) NSIndexPath *lastSelected;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[orderTableDelegate receiveSelectedArticleName:[[articles objectAtIndex:indexPath.row] name]];
self.firstSelected = nil;
self.firstSelected = self.lastSelected;
self.lastSelected = nil;
self.lastSelected = [indexPath retain];
if (self.firstSelected == self.lastSelected) {
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:self.firstSelected] withRowAnimation:CELL_ANIMATION];
[self.firstSelected release];
[self.lastSelected release];
self.firstSelected = nil ;
self.lastSelected = nil ;
} else {
if (self.firstSelected != nil) {
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:self.firstSelected] withRowAnimation:CELL_ANIMATION];
}
if (self.lastSelected != nil) {
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:self.lastSelected] withRowAnimation:CELL_ANIMATION];
}
}
if ([searchBar isFirstResponder]) {
[searchBar resignFirstResponder];
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这让我相信 lastSelected 是一个实例变量?如果是这种情况,则说明您没有正确保留它,并且无法保证它超出此方法的范围仍然存在。如果您要在执行后使用它,则需要保留 didSelectRowAtIndexPath: 参数中传递的 indexPath。
请记住,如果您这样做,则需要在整个方法中进行更好的内存管理...即在更改其值或将其设置为 nil 之前释放 lastSelected。
假设firstSelected和lastSelected是实例变量,你可以这样做。 (如果您让它们保留属性并使用设置器,所有释放和 != 检查都会消失)
This leads me to believe that lastSelected is an instance variable? If this is the case, you are not properly retaining it, and there is no guarantee that it is still alive beyond the scope of this method. The indexPath passed in the didSelectRowAtIndexPath: argument needs to be retained if you are going to use it after it's execution.
Keep in mind, if you do that, you need better memory management throughout that method...i.e. releasing lastSelected before changing it's value or setting it to nil.
Assuming firstSelected and lastSelected are instance variables, you could do something like this. (all the releasing and != checking would go away if you made them retained properties and used the setter)