我仍然相对较新的iOS编程。这是一个困扰我很长时间的问题。
因此,在其中一个视图控制器中,在将此视图控制器推入导航项之前,我在前一个视图控制器的prepareForSegue
中向其传递一个参数,例如userId。当此视图控制器基于前一个视图控制器的userId
加载(初始化)时,我正在进行网络调用以获取与该用户相关的信息列表,然后将此信息填充到模型中。当前的视图控制器。
我应该把这个数据准备的逻辑放在哪里?
答案 0 :(得分:1)
- (void) viewDidLoad {
[super viewDidLoad];
// initialize stuff
}
虽然,最好进行网络调用并将所有这些信息收集到包含所有信息的自定义类中,然后执行segue。然后,您需要在新视图控制器中执行的操作是从对象中提取数据(这仍将在viewDidLoad
中完成)。
可以说,这种方法可能更好,因为如果网络出现问题,您可以显示错误消息,然后不执行segue,让用户更轻松地重新尝试相同的操作,或者至少他们会离开应用程序以检查网络设置并返回后,在页面上重新尝试相同的操作。
当然,如果出现网络错误,你可以一直向前推进,然后向后移动,但我认为这看起来很蹩脚。
另外,值得注意的是,如果您使用UICollectionView
或UITableView
来展示信息,那么呈现逻辑可以(应该)移出viewDidLoad
并进入集合/表数据源方法。
答案 1 :(得分:1)
使用viewDidLoad:
应该可以正常使用故事板,因为故事板不会重复使用视图控制器。无论如何,为了我的视图控制器使用场景的完整性,我倾向于使用这种模式:
viewWillAppear:
viewWillDisappear:
这可确保您的数据始终更新为当前userId
,因为ID可能会在viewDidLoad
之后更改,例如如果在设置.view
之前视图控制器重用或访问userId
属性。
您还应该跟踪您的数据是否已加载。例如,您可以创建名为_isDataLoaded
的私有布尔字段,在完成加载数据时将其设置为true
,并在取消加载数据或设置新false
时将其设置为userId
总结一下,我的想法中的模式应该是这样的:
@interface UserViewControler : UIViewController {
bool _isDataLoaded;
NSURLConnection _dataConnection;
}
@implementation UserViewController
-(void) setUserId:(int)userId {
if (_userId != userId) {
_userId = userId;
_isDataLoaded = false;
}
}
-(void) viewWillAppear:(BOOL)animated {
if (!_isDataLoaded) {
_dataConnection = // init data connection here
_dataConnection.delegate = self;
[_dataConnection start];
}
}
-(void) viewWillDisappear:(BOOL)animated {
if (_dataConnection) {
[_dataConnection cancel];
_dataConnection = nil;
_isDataLoaded = false;
}
}
// NSURLConnection call this when finish
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
_isDataLoaded = true;
_dataConnection = nil;
}
// NSURLConnection call this when fail to load data
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
_isDataLoaded = false;
_dataConnection = nil;
}
这取决于您使用什么框架从远程服务器检索数据,但模式应该是这样的。这将确保:
userId
相同,则不会再次下载数据。答案 2 :(得分:0)
我过去所做的是制作自定义初始化程序。
+(instancetype)initWithUserID:(NSString)userID;
以下是实施示例。
+(instancetype)initWithUserID:(NSString *)userID {
return [[self alloc] initWithUserID:userID];
}
-(id)initWithUserID:(NSString *)userID {
self = [self initWithNibName:@"TheNameOfTheNib" bundle:nil];
if(self) {
_userID = userID;
}
//do something with _userID here.
//example: start loading content from API
return self;
}
-(void)viewDidLoad {
//or do something with userID here instead.
}
我建议的另一件事是创建一个加载数据并使用块的自定义类。
然后你可以做这样的事情
[API loadDataForUserID:userID withCompletionBlock^(NSArray *blockArray) {
//in this case I changed initWithUserID to initWithUsers
[self.navigationController pushViewController:[NextController initWithUsers:blockArray] animated:YES];
}