我是编程方面的新手,我目前正在查看我遇到一些问题的块。我很难到达在我的区块内定义的对象。实际上我无法以一种准确的方式解释这个问题,所以生病给你一些代码和图片,并希望它有意义,并且你原谅我狡猾的知识并试图帮助我理解这个问题。
所以我开始运行这个块
- (void)fetchSite
{
//Initiate the request...
[[FeedStore sharedStore] fetchSites:^(RSSChannel *objSite, NSError *err) {
//When the request completes, this block will be called
if (!err) {
//If everything went ok, grab the object
channelSite = objSite;
//Now we need to extract the first siteId and give it to sharedstore
RSSItem *site = [[channelSite sites] objectAtIndex:0];
NSString *currentSiteId = [NSString stringWithFormat:@"%@", [site siteNumber]];
NSLog(@"DEBUG: LVC: fetchSite: currentSiteId: %@", currentSiteId);
[[FeedStore sharedStore] setCurrentSiteId:currentSiteId];
//Now we can call fetchEntries
[self fetchEntries];
} else {
//If things went bad, show an alart view
UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Fel" message:@"Kunde inte bedömma din position relaterat till närmaste hållplats, försök gärna igen" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[av show];
//Stop UIRefreshControl
[refreshControl endRefreshing];
}
}];
}
然后调用fetchEntries:
- (void)fetchEntries
{
void (^completionBlock)(RSSChannel *obj, NSError *err) = ^(RSSChannel *obj, NSError *err) {
if (!err) {
//If everything went ok, grab the object, and reload the table and end refreshControl
channel = obj;
//Post notification to refreshTableView method which will reload tableViews data.
[[NSNotificationCenter defaultCenter] postNotificationName:@"RefreshTableView" object:nil];
//Stop UIRefreshControl
[refreshControl endRefreshing];
} else {
//If things went bad, show an alart view
UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Fel" message:@"Kunde inte hämta avgångar för din hållplats, försök gärna igen" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[av show];
//Stop UIRefreshControl
[refreshControl endRefreshing];
}
};
//Initiate the request...
if (fetchType == ListViewControllerFetchBus) {
[[FeedStore sharedStore] fetchDepartures:completionBlock];
selectedSegment = 0;
} else {
[[FeedStore sharedStore] fetchDeparturesMetro:completionBlock];
selectedSegment = 1;
}
}
重新加载表:
- (void)refreshTableView:(NSNotification *)notif
{
[[self tableView] reloadData];
}
在我填充自定义表格单元格的地方:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Get received data from fetchEntries block
RSSItem *item = [[channel items] objectAtIndex:[indexPath row]];
//Get the new or recycled cell
ItemCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ItemCell"];
//Set the apperance
[[cell lineNumberLabel] setTextColor:[UIColor whiteColor]];
[[cell lineNumberLabel] minimumScaleFactor];
[[cell lineNumberLabel] setFont:[UIFont boldSystemFontOfSize:22]];
[[cell lineNumberLabel] adjustsFontSizeToFitWidth];
[[cell lineNumberLabel] setTextAlignment:NSTextAlignmentCenter];
[[cell destinationLabel] setTextColor:[UIColor whiteColor]];
[[cell displayTimeLabel] setTextColor:[UIColor whiteColor]];
[[cell displayTimeLabel] setTextAlignment:NSTextAlignmentLeft];
//Configure the cell with the item
if ([item lineNumber]) [[cell lineNumberLabel] setText:[item lineNumber]];
if ([item destination]) [[cell destinationLabel] setText:[item destination]];
if ([item displayTime]) [[cell displayTimeLabel] setText:[item displayTime]];
if ([item displayRow1]) [[cell destinationLabel] setText:[item displayRow1]];
return cell;
}
因此,当我在正常状态下运行这些块时,一切都像魅力一样。
但问题是从我从UIActionSheet调用fetchSite方法开始,或实际上是从UIAegmentedControl(UIActionSheet的子视图)调用时,会发生在这里:
- (void)displayPickerView
{
//First im creating an instance to PickerViewController which will handle the UIPickerView which is a subview of UIActionSheet. pickerArrayFromChannel holds entries for UIPickerView to show in its ViewController.
pickerViewController = [[PickerViewController alloc] init];
[pickerViewController initWithItems: pickerArrayFromChannel];
pickerViewController.delegate = self;
//initiate UIActionSheet which needs no delegate or appearance more than its style
actionSheet = [[UIActionSheet alloc] initWithTitle:nil
delegate:nil
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
[actionSheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];
//Create frame and initiate a UIPickerView with this. Set its delegate to the PickerViewController and set it to start at row 0
CGRect pickerFrame = CGRectMake(0, 40, 0, 0);
UIPickerView *pickerView = [[UIPickerView alloc] initWithFrame:pickerFrame];
pickerView.showsSelectionIndicator = YES;
pickerView.delegate = pickerViewController;
pickerView.dataSource = pickerViewController;
[pickerView selectRow:0 inComponent:0 animated:YES];
//Add this pickerView as subview to actionSheet
[actionSheet addSubview:pickerView];
//Now, create two buttons, closeButton and okButton. Which really are UISegmentedControls. Action to closeButton is (for now) dismissActionSheet which holds only following code " [actionSheet dismissWithClickedButtonIndex:0 animated:YES]; " and works fine
UISegmentedControl *closeButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:@"Stäng"]];
closeButton.momentary = YES;
closeButton.frame = CGRectMake(260, 7.0f, 50.0f, 30.0f);
closeButton.segmentedControlStyle = UISegmentedControlStyleBar;
closeButton.tintColor = [UIColor blackColor];
[closeButton addTarget:self action:@selector(dismissActionSheet) forControlEvents:UIControlEventValueChanged];
[actionSheet addSubview:closeButton];
//OK button
UISegmentedControl *okButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:@"Visa avgångar"]];
okButton.momentary = YES;
okButton.frame = CGRectMake(10, 7.0f, 100.0f, 30.0f);
okButton.segmentedControlStyle = UISegmentedControlStyleBar;
okButton.tintColor = [UIColor blueColor];
[okButton addTarget:self action:@selector(updateDeparturesFromActionSheet) forControlEvents:UIControlEventValueChanged];
[actionSheet addSubview:okButton];
//Now show actionSheet
[actionSheet showInView:[[UIApplication sharedApplication] keyWindow]];
[actionSheet setBounds:CGRectMake(0, 0, 320, 485)];
}
现在让我们看看updateDeparturesFromActionSheet方法,我们已经接近我的问题开始的地方(如果你还在阅读,谢谢你
- (void)updateDeparturesFromActionSheet
{
//Dismiss the actionSheet
[actionSheet dismissWithClickedButtonIndex:0 animated:YES];
//Send the selected entry from UIPickerView to currentAddress property in FeedStore, fetchSite method will eventually use this
[[FeedStore sharedStore] setCurrentAddress:[pickerViewController addressFromPickerView]];
//Call fetchSite method
[self fetchSite];
}
fetchSite然后最终调用fetchEntries方法,最终填充我的表。我将收到的obj(来自块)存储在名为channel
的属性中void (^completionBlock)(RSSChannel *obj, NSError *err) = ^(RSSChannel *obj, NSError *err) {
if (!err) {
//If everything went ok, grab the object, and reload the table and end refreshControl
channel = obj;
频道对象看起来像这样
channel RSSChannel * 0x07464340
NSObject NSObject
currentString NSMutableString * 0x00000000
lvc ListViewController * 0x08c455d0
items NSMutableArray * 0x08c452d0
sites NSMutableArray * 0x08c452f0
parentParserDelegate id 0x00000000
pickerViewArray NSMutableArray * 0x08c45320
正如您在我填充表格单元格时所看到的那样,我使用了通道对象内部项目的信息。
现在,如果你还在我身边(并且已经睡着了)到目前为止,我将解释我的实际问题,现在当你(希望)有所有相关代码时。
因此,当我在UIActionSheet中按 okButton 时,会调用updateDeparturesFromActionSheet方法。哪个调用最终调用fetchEntries的fetchSite,到目前为止一直很好,这些块执行并返回信息。但是当我抓住fetchEntries obj 并将其放入频道时,它似乎并没有“更新”此对象,而是使用块 obj 对象。其中似乎 channel 对象在内存中获得一个新位置(它保持0x07464340)。 我的第一个想法是确保ARC释放通道对象,删除该对象的所有所有者,但似乎即使我这样做(然后用简单的NSLog(@@)再次检查它的null。 “%@”)当我触发“更新”时,它会继续获取旧值和内存引用。
经过多次尝试发布频道对象并做各种事情(创建新数组(在块之外)等)。我一直在想,我不理解的一些特殊规则是在弄乱我。有什么想法吗?
如果有什么不清楚,请告诉我,因为我表达了自己的不好,很难解释一个你不了解自己的问题。谢谢你提前。