iOS开发新手。所以我传递了一个带有对象地址的方法,认为我会改变同一个对象:
_posts = [[NSMutableArray alloc]init];
FetchPosts *dataControl = [[FetchPosts alloc]init];
[dataControl accessPosts: _posts];
以下代码接收传入的对象。
-(void)accessPosts: (NSMutableArray *)transition {
//access the posts here.
_readablePosts = transition;
NSURL *url = [NSURL URLWithString: @"private"];
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url];
[NSURLConnection connectionWithRequest:request delegate:self];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
_jsonPosts = [[NSMutableData alloc]init];
[_jsonPosts appendData: data];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSError *error;
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:_jsonPosts options:NSJSONReadingAllowFragments error:&error];
for(int i = 0; i<jsonArray.count; i++) {
NSDictionary *element = jsonArray[i];
Posts *newPost = [[Posts alloc]init];
newPost.title = element[@"Title"];
newPost.discovery = element[@"Discovery"];
newPost.summary = element[@"Description"];
newPost.contact = element[@"Contact"];
[_readablePosts addObject:newPost];
}
}
从我的角度来看,一切似乎都恰到好处。但是,当我返回原始方法时,_posts不能保存正确的对象。我在这里指点错了吗?
答案 0 :(得分:2)
你称这种方法 -
[dataControl accessPosts: _posts];
调用
[NSURLConnection connectionWithRequest:request delegate:self];
这是一种非阻塞方法,因此它会立即返回并在检索到要处理的数据后调用委托方法。
如果您在_posts
返回后立即访问accessPosts
,则会在从网络检索数据之前执行此操作。
只有在connectionDidFinishLoading:
被调用后才能访问_posts
一种解决方案是使用委托模式。您的外部代码会将自己设置为FetchPosts
对象的委托,并从connectionDidFinishLoading
调用委托方法。这不仅可以解决您的异步问题,还可以避免对NSMutableArray
进行不安全的更新,并避免使用副作用。
您需要在FetchPosts.h
中创建适当的协议,但之后您可以使用类似 -
-(void) requestPosts {
FetchPosts *dataControl = [[FetchPosts alloc]init];
dataControl.delegate=self;
[dataControl accessPosts];
}
-(void) didReceiveNewPosts:(NSArray *)posts {
// Do something with posts
}
<强> FetchPosts.m 强>
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSError *error;
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:_jsonPosts options:NSJSONReadingAllowFragments error:&error];
for(int i = 0; i<jsonArray.count; i++) {
NSDictionary *element = jsonArray[i];
Posts *newPost = [[Posts alloc]init];
newPost.title = element[@"Title"];
newPost.discovery = element[@"Discovery"];
newPost.summary = element[@"Description"];
newPost.contact = element[@"Contact"];
[_readablePosts addObject:newPost];
}
if ([self.delegate respondsToSelector:@selector(didReceiveNewPosts:)]) {
[self.delegate didReceiveNewPosts:_readablePosts];
}
}
答案 1 :(得分:0)
我认为json是空的,每次设备获取一块数据时都会调用didReceiveData方法,在下载过程中可以多次调用此方法。如果您创建一个新的可变数据,并且附加数据就像您正在重置NSDAta对象一样 您应该在didReceiveresponse中创建Json post对象。