提问人:Arainty 提问时间:2/28/2021 更新时间:3/6/2021 访问量:113
ARC 和指针存储
ARC and pointer storing
问:
我的情况比我在发帖之前看到的要复杂一些,而且我不太擅长内存管理。
我有一个自定义(我们将在此处调用),并且在单击它时将其指针传递给(此处)。我传递指针是因为我想调用这个单元格的方法,并且引用只能通过 Objective-C 中的复制进行,所以它不会调用右侧单元格上的方法。我做了这个:UITableViewCell
MyCell
UITableViewController
MyController
MyController.h
@interface MyController : UITableViewController {
MyCell * __autoreleasing *_cell;
}
-(instancetype)initWithCell:(MyCell * __autoreleasing *)cell;
@end
MyController.m
- (instancetype)initWithCell:(MyCell **)cell {
if (self = [super init]) {
_cell = cell;
// Checkpoint 1
}
}
然后,我想稍后在我的代码中使用此变量,例如定义节数:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Checkpoint 2
return (*_cell).contents.count; // contents being an NSArray property of the custom cell
}
问题:在这里标记的“检查点”,我有一个 ,但是它在第一个检查点中显示 2(正确的数字),但在第二个检查点中显示 0,所以基本上当我单击单元格时会显示一个空的表格视图。NSLog(@"%ld", (unsigned long)(*_cell).contents.count);
我曾经通过将单元格存储在属性中来通过副本传递单元格,并且一切正常,但是由于指针引用而将调用从 更改为,正如我所说,视图现在是空的。这可能是一个内存管理问题,但我不知道如何解决它(对 Objective-C 来说相当新,第一个应用程序)。nonatomic, strong
self.cell
_cell
注意:我试图将 更改为 ,但这会导致每次访问 的属性时都会崩溃。我也尝试使用属性来存储它而不是使用 ivar,但它并没有解决我的问题。__autoreleasing
__strong
_cell
nonatomic, assign
谢谢!
编辑:忘了提到我使用
[self.navigationController pushViewController:[[MyController alloc] initWithCell:(MyCell **)&cell] animated:YES];
在我之前的视图控制器中,在方法中。tableView:didSelectRowAtIndexPath:
答:
几点:
该模式有一个非常具体的用途,即被调用方法创建一个对象,并且需要更新调用方的指针来引用这个新对象。例如,考虑正则表达式文档中的示例:
* __autoreleasing *
NSError *error = NULL; NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\b(a|b)(c|d)\\b" options:NSRegularExpressionCaseInsensitive error:&error];
所以,是一个指针,调用方是 向该指针提供地址,以便在实例化对象时,它可以更新调用方的引用以指向该指针。
error
NSError
regularExpressionWithPattern
NSError
唯一需要使用此“指向指针的指针”模式的情况 当被调用的例程正在实例化一个对象并希望 更新调用例程的指针。我们通常只需要 当您想要返回指向多个指针的指针时,请使用该模式 对象(例如,在 的情况下,它将 返回指针,但也可以选择返回指针 也想更新指针)。
regularExpressionWithPattern
NSRegularExpression *
NSError *
你说:
我传递指针是因为我想调用这个单元格的方法,并且引用只能通过 Objective-C 中的复制进行,所以它不会调用右侧单元格上的方法。
这种逻辑并不完全正确。 是指向该的指针 原始对象,而不是它的副本。您可以在没有 求助于“指针到指针”模式。就您而言,如果 你只会使用 ,而不是 .
MyCell *
MyCell *
MyCell * *
您根本不应该将单元格引用传递给此视图控制器...一个视图控制器不应进入另一个视图控制器的视图层次结构;
表视图具有与单元格重用相关的各种优化...不应在其自己的表视图数据源和委托方法中使用除交互之外的单元格;和
不应使用单元格(“视图”对象)来存储“模型”数据(当前存储在属性中的内容)。不要将“模型”(数据)与“视图”(UI)混为一谈。
contents
因此,我建议使用指向模型对象的简单指针(而不是指向指针的指针):
@interface MyController : UITableViewController
@property (nonatomic, strong) NSArray <ModelObject *> *contents; // or whatever you previously stored in cell `contents`
@end
然后:
MyController *controller = [[MyController alloc] init]; // usually we'd instantiate it using a storyboard reference, but I'm gather you're building your view hierarchy manually
controller.contents = self.contents[indexPath.row]; // note, not `cell.contents`, but rather refer to this current view controller’s model, not the cell (the “view”)
[self.navigationController pushViewController:controller animated:YES];
有关向视图控制器传递数据和从视图控制器传递数据的信息,请参阅在视图控制器之间传递数据。但是,作为一般规则,一个视图控制器不应访问另一个视图控制器的视图对象。
评论
MyCell
MyCell
评论
MyCell
MyController