How to call the RefreshTableView function in objective C? - objective-c

I wrote a Refresh function to reload the tableview in iPhone app with the argument of UITableview.
My question is how can I call or invoke this refresh function?
- (void)RefreshTableView:(UITableView *)tableView
{
if(tableView != nil){
[tableView reloadData];
}
}

First of all rename your method like the following:
- (void)refreshTableView:(UITableView *)tableView
Then, to call that method you need to perform the following:
[self refreshTableView:yourTableview];
where self stands for the object that will receive the message. In this case self is an instance of the object that contains that method.
Now, why do you need to pass also an instance of the table view?
if you have a instance variable for that table view and you have synthesized it (#property/#synthesize pattern), you could simple do the following:
- (void)refreshTableView
{
[[self myTable] reloadData];
}
and then invoke that method like the following:
[self refreshTableView];
Edit
As danh suggested, if you have a property (or an instance variable), you can also call directly
[[self myTable] reloadData]; // or [self.myTable reloadData];
without passing through refreshTableView.

If - (void)RefreshTableView:(UITableView *)tableView is in the same file then you can call it
[self RefreshTableView:aTableView]; when you want to call.

from the class itself [self RefreshTableView:yourTableView];
form outside of the class [yourClassInstance RefreshTableView:yourTableView];
P.S:
You should refactor your code and rename RefreshTableView: with refreshTableView:

Related

Use of undeclared identifier in my Objective-C code

I'm a newbie to Objective-C and I'm trying to a access a global variable and I can not. What have I missed?
This is the variable: getShoppingCartRequestSuccessful
-(void)setShoppingCartGetRequestWithNetworkManager//watch the bag button->4 {
//Sets the loading indicator on. [self setLoadingIndicator];
//NetworkManager [[NetworkManager sharedManager] setDelegate:self];
//GetShoppingCart [[NetworkManager sharedManager]
requestGetShoppingCartWithParameters:[[ServerRequestBuilder sharedManager]
returnParametersDictionaryForGetShoppingCartWithCustomerID:strCustomerID]];
//update shopping cart-getShoppingCartRequestSuccessful [[GlobalVariables sharedManager] setObject:shoppingCartSummary
forKey:GLOBALVARIABLES_SHOPPINGCARTSUMMARY overwrite:YES];
}
This is the argument I want to pass:
-(void)getShoppingCartRequestSuccessful:(MNShoppingCart *)shoppingCart withOpertaion:(AFHTTPRequestOperation *)operation
{
if (shoppingCart) {
MNShoppingCartSummary *shoppingCartSummary = [[MNShoppingCartSummary alloc] initShoppingCartSummaryWithCustomerID:[[shoppingCart getCustomerInfoModel] getCustomerInfoID] andWithTotalAmountOfProducts:[shoppingCart getAmountOfProducts] andWithTotalPrice:[shoppingCart getTotalPrice]];
[[GlobalVariables sharedManager] setObject:shoppingCartSummary forKey:GLOBALVARIABLES_SHOPPINGCARTSUMMARY overwrite:YES];
NSLog(#"price val call Func #6");
[self setShoppingCartScreenWithShoppingCartModel:shoppingCart withDeliveryAreaChange:YES];
}
getShoppingCartRequestSuccessful is an instance method. Not a variable. Instance method is basically a "function" that can return something or even nothing (void) to the caller. In your case, is returning a void.
When you see instance method, like this
-(void)goDoSomething:(NSString *)name
To call it, if the method is in the same Viewcontroller (ie. Class), then you do it like this:
[self goDoSomething:#"Moran"];
As you can see, goDoSomething expects ONE parameter of type NSString, so you have to give it that. This will execute the method.
In your case,
-(void)getShoppingCartRequestSuccessful:(MNShoppingCart *)shoppingCart withOpertaion:(AFHTTPRequestOperation *)operation
means, you need to pass 2 parameters to it.
To use this method, you call:
[self getShoppingCartRequestSuccessful:yourCart withOpertaion:operation];
you need to have the yourCart and operation ready before passing it to this method.
ps. withOpertaion is wrong spelling.

How to replace pickerView:numberOfRowsInComponent method for 1 instance of pickerView

I want to create a pickerView programmatically and have it use it's own version of a method like pickerView:numberOfRowsInComponent.
I create the instance at runtime like this:
UIPickerView *myPickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 200, 320, 200)];
myPickerView.delegate = self;
myPickerView.dataSource = self;
myPickerView.showsSelectionIndicator = YES;
[self.view addSubview:myPickerView];
The standard method called would be:
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
NSUInteger numRows = 5;
return numRows;
}
What I want to do is replace this standard method with another method for this instance only.
-(NSInteger)xxxpickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{ // special method for this instance only
return 1;
}
I've been able to use method swizzle to do this with other things, but I can't seem to get it to work with UIPickerView.
#implementation UIPickerView (Tracking)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
SEL originalSelector = #selector(pickerView:numberOfRowsInComponent:);
SEL swizzledSelector = #selector(xxxpickerView:numberOfRowsInComponent:);
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
BOOL didAddMethod =
class_addMethod(class,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
});
}
I've listed the methods to see if the 2nd method was added to the instance during runtime and it is in the list.
However, the 2nd method doesn't run, the 1st method does run.
Here's a link to the post that got me started on this, and I've confirmed it works, but I seem to be missing something about this.
http://nshipster.com/method-swizzling/
I'm open to other suggestions, the problem I'm trying to solve is that I want to create the instance of a UIPickerView object that won't be dependent on another instance that will be running at the same time. So I want a different method that will work only with the one instance and completely ignore any other instances that might be running and I want to do this programmatically.
At lest one reason for not using a tag/switch, is that I don't know what the conditions will be until runtime.
I don't know why swizzle would work with one object and not another, and I'm open to other way to replace stock methods with others at runtime.
Is there something about the method I'm trying to replace that won't allow it to be replaced?
EDIT: in order to try and make the question clear, the following code in the link works. It swaps one method for another method. What I need to do is the same thing for another object and I can't figure out what it works for 1 object and not another.
This works for another object: http://nshipster.com/method-swizzling/
Here's another link as well: http://blog.newrelic.com/2014/04/16/right-way-to-swizzle/
One simple way to do it is keep a copy of the pointer in a property and then compare pointers in the datasource/delegate methods.
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if ( pickerView == self.myPickerView )
return 1; // response for this particular picker view
else
return 5; // standard response
}

UITableViewDataSource and Multithreading

I'm running into index beyond bounds exception in one of my UITableViews and I think it could be down to some multithreading issues. Here's what I believe is happening:
I have a UITableView and it's data source is a regular NSMutableArray.
This NSMutableArray which is backing my UITableView is updated every couple of seconds with the contents of an API response.
After each update, UITableView's reloadData is being invoked to ensure that the user sees new data from the API server.
Sometimes a index beyonds bounds exception gets thrown.
Here's my code:
-(NSMutableArray*) currentBetEvents
{
return currentMarketId == nil ? [[BFOpenBetsModel sharedInstance] betEvents] : filteredBetEvents;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
NSArray *betEvents = [self currentBetEvents];
return [betEvents count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSArray *betEvents = [self currentBetEvents];
id obj = [betEvents objectAtIndex:indexPath.section] // this is where it blows up
Basically, I get an exception while trying to access an object in the betEvents structure at index 0.
What I believe is happening is:
reloadData is called on the UITableView
numberOfSectionsInTableView: is invoked which returns a value > 0.
a rouge thread arrives and clears out the UITableView's data source.
cellForRowAtIndexPath: is invoked and it bombs.
Is there any way to ensure that this doesn't happen? Do I need to start using some primitive locks on the data source to ensure that it doesn't get updated while the table is being updated?
EDIT
Took another look at how the data structures returned by currentBetEvents can be altered and it looks like the filteredBets & betEvents can be cleared out as a result of the following code:
[[NSNotificationCenter defaultCenter] postNotificationName:kUserLoggedOutNotification object:nil];
This notification is posted whenever the user logs out. Whenever a user logs out of the app, I need to clear out the filteredBets and betEvents arrays. Is it possible that the following could happen:
reloadData is called on the UITableView
numberOfSectionsInTableView: is invoked which returns a value > 0.
User logs out which kicks off the notification & clears out the data structures.
cellForRowAtIndexPath: is invoked and it bombs.
Thanks,
Sean
Definitely sounds like a threading problem. You might try something like this:
// view controller
#synchronized([[BFOpenBetsModel sharedInstance] betEvents])
{
[self.tableView reloadData];
}
…
// data model
#synchronized(_betEvents) // or whatever the instance variable -betEvents returns is
{
[_betEvents addObject:whatever];
}

Calling a method in a different view and then showing that view

I have a viewController called "chooseDateViewController" where in the .m file it takes input from the user and puts into a string. I have another viewController called "showTable" where I have a custom made table that takes the dates in the string. the table is generated (in showTable.m) based on the dates (which are strings).
I want to be able to call "showTableViewController" view controller when the user enters the data and presses a button so then they are taken to the showTableViewController with there dates nicely displayed but my problem is I cannot pass the data from the "chooseDate" View controller to a method in "showTable". This is how I did it but it is not working... I tried to NSLog it but its not even entering the function. If anyone knows why, it would be much appreciated.
Thanks
// In chooseDateViewController.m
-(void) sendValue {
NSString *date= #"July 25 2012";
UIViewController *view5 = [[showTableViewController alloc] initWithNibName:#"showTableViewController" bundle:nil];
[self.navigationController pushViewController:view5 animated:YES];
[view5 receiveNumbers:date]; //trigger the method in showTable.m
[view5 release];
}
// showTableViewController.m
-(void) receiveNumbers: (id) sender {
NSLog (#"data received is %#", sender);
}
Perhaps you can initialize the viewController with the information, so for example, you can have a line that is like:
UIViewController *view5 = [[showTableViewController alloc] initWithSomeInfo: (the structure that houses the data)];
Then in the custom init method of the showTableViewController, you can process the data before you are pushing the view controller.
I hope this helps,
Tams
Here is some code that you were looking for:
In the showTableViewController, you have have a variable to hold the passed in information so:
- (id)initWithSomeInfo(NSArray*)info{
self = [super init];
if(self){
myOwnVariable = info;
[self processInfo:myOwnVariable];
}
return self;
}

Objective C - UITableViewCell crashing on scroll

I have a UITableViewCell with a method like this.
-(void) setupStore:(StoreModel *) store {
self.title.text = store.title; // crash here when scrolling
}
So that method is called from within a UIViewController class that contains the UITableView.
Something like this
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
[cell setupStore:[storesArray objectAtIndex:indexPath.row]];
...
}
That works when the table first loaded, but when I scroll the table, it crash with error EXC_BAD_ACCESS.
What could be causing that?
Please enlight.
Thanks,
Tee
Try to build your code with NSZombieEnabled = YES and report here what is happening. Give us the full error description.
http://cocoa-nut.de/?p=16
In general We will get EXC_BAD_ACCESS when we are trying to use a released object.
So you can check whether you are using any released object.
As you have mentioned that storesArray = [[[storesLocation alloc] init]retain]; there is no need to retain the object. Give a try by using this line
storesArray = [[storesLocation alloc] init];.
Also make sure that storemodel object exists by logging it in this method
-(void) setupStore:(StoreModel *) store
{
NSLog(#"store model %#",store);
}
You can go through the link
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html