将保留对象分配给弱属性

9

我正在使用 Xcode 6,并且我已经创建了一个包含 UITableView自定义单元格 的应用程序。 这是我的自定义单元格

@interface SuggestingTableViewCell : UITableViewCell

@property (nonatomic, weak) IBOutlet SuggestedSeriesView *seriesOne;
@property (nonatomic, weak) IBOutlet SuggestedSeriesView *seriesTwo;
@property (nonatomic, weak) IBOutlet SuggestedSeriesView *seriesThree;
@property (nonatomic, weak) IBOutlet SuggestedSeriesView *seriesFour;

@end

如您所见,我有四个 IBOutets 连接到一个 SuggestedSeriesView 的子类 UIView 上。 在 TableView DataSource 方法中,我创建了这些 SuggestedSeriesView 并像这样分配它们:

cellIdentifier = suggestionCell;
SuggestingTableViewCell *suggesting = (SuggestingTableViewCell *)[tableView dequeueReusableCellWithIdentifier:suggestionCell];
Series *ser1 = series[0];
suggesting.seriesOne = [[SuggestedSeriesView alloc] initWithFrame:suggesting.seriesOne.bounds
                                                    andSeriesData:@{JV_SERIES_IMAGE_URL : ser1.imageURL,
                                                                    JV_SERIES_TITLE : ser1.title}];
Series *ser2 = series[1];
suggesting.seriesTwo = [[SuggestedSeriesView alloc] initWithFrame:suggesting.seriesTwo.bounds
                                                    andSeriesData:@{JV_SERIES_IMAGE_URL : ser2.imageURL,
                                                                    JV_SERIES_TITLE : ser2.title}];
Series *ser3 = series[2];
suggesting.seriesThree = [[SuggestedSeriesView alloc] initWithFrame:suggesting.seriesThree.bounds
                                                      andSeriesData:@{JV_SERIES_IMAGE_URL : ser3.imageURL,
                                                                      JV_SERIES_TITLE : ser3.title}];
Series *ser4 = series[3];

suggesting.seriesFour = [[SuggestedSeriesView alloc] initWithFrame:suggesting.seriesFour.bounds
                                                     andSeriesData:@{JV_SERIES_IMAGE_URL : ser4.imageURL,
                                                                     JV_SERIES_TITLE : ser4.title}];

编译器给我警告:
将保留对象分配给弱属性; 分配后对象将被释放
为什么这种情况会发生在 `SuggestedSeriesView` 被 `cell` 保留的时候,因为它没有 `IBOutlet`?
感谢您的帮助。

1
不,它并不是这样,这正是重点所在。保留不会发生是因为东西是“IBOutlet”,而是因为东西是“strong”。 - The Paramagnetic Croissant
3个回答

19

这是因为您的属性较弱,这意味着它们不会保留任何东西,只能引用其他内容。

IBOutlet 等同于 void,它只是一个提示,告诉 Xcode“这可以在界面构建器上连接”。

从界面构建器中获取的属性之所以是弱类型,并且 IBOutlet 是因为它们由故事板的视图控制器视图本身保留,因此如果您在界面构建器中创建了一个视图控制器并添加视图,然后将此视图链接到代码中,您的属性就不必是 strong,因为它已经被视图之一保留。

您应将这些属性更改为

@property (nonatomic, strong) SuggestedSeriesView *seriesOne;
@property (nonatomic, strong) SuggestedSeriesView *seriesTwo;
@property (nonatomic, strong) SuggestedSeriesView *seriesThree;
@property (nonatomic, strong) SuggestedSeriesView *seriesFour;

7
这个说法不正确。Outlets可以是weak的,因为它们是某个视图控制器的子视图,而父视图会对其子视图保持强引用。 - jrturton

10
您正在创建一个对象并同时将其分配给一个弱属性。此时,没有任何东西对它有强引用,因此根据ARC的规则,应立即将其设置为nil。(请注意,在运行调试构建时,并不会立即发生这种情况)。
从storyboard中加载时,对象被创建,作为子视图添加,然后再分配给outlet。父视图有一个强引用,所以这是可以的。
为了反映这种行为而不改变您的outlet属性类型(尽管说实话现在没什么坏处),您应该将您的新对象分配给一个本地变量,然后将其添加到一个视图中,最后将其分配给outlet属性。

好的,谢谢。我想现在我会更改属性属性 :) - YYfim

1
@interface SuggestingTableViewCell : UITableViewCell

@property (nonatomic, weak) IBOutlet SuggestedSeriesView *seriesOne;

@end

cellIdentifier = suggestionCell;

SuggestingTableViewCell *suggesting = (SuggestingTableViewCell *)[tableView dequeueReusableCellWithIdentifier:suggestionCell];

Series *ser1 = series[0];

SuggestedSeriesView * strongSeriesOne = [[SuggestedSeriesView alloc] initWithFrame:suggesting.seriesOne.bounds andSeriesData:@{JV_SERIES_IMAGE_URL : ser1.imageURL, JV_SERIES_TITLE : ser1.title}];

suggesting.seriesOne = strongSeriesOne;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接