Hey all, this should be a simple task but for some reason i am making it harder... I am trying to save some text from an XML file to a NSString. But when i debug it, the string says "Out of scope".
Here is my code:
in my .h file:
#interface RootViewController : UIViewController<MBProgressHUDDelegate> {
NSString *thePW;
}
and my .m file:
NSString *thePW;
...
- (void)viewDidLoad {
...
if(e == nil){
NSString *response = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
thePW = response; // <-- this is where it has "Out of scope"
[response release];
}
}
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex != [alertView cancelButtonIndex])
{
if (thePW == #"0000")
{
NSLog(#"correct!");
}
}
}
You may also try:
thePW = [NSString stringWithFormat:#"%#",response]; // to assign the string value.
and
while comparing strings:
(thePW isEqualToString #"0000")
Drop the redeclaration of thePW in your .m file
Also, if you want to keep the value of response in thePW be sure to retain it as well.
Related
i am facing problem when i call method within method of another class like this i have method for button when someone click on button
//within ViewController.m button method
-(IBAction)login:(id)sender
{
DBHelper *objdb = [[DBHelper alloc] init];
[objdb loginnow:textname.text andpassword:textpassword.text];
}
and this button method calling this method in DBhelper.m file and it succesfully calling this method
-(void) loginnow:(NSString *) username andpassword:(NSString *) password
{
[self createEditableCopyOfDatabaseIfNeeded];
[self initializeDatabase];
const char *sql;
NSString *querySQL = [NSString stringWithFormat: #"SELECT username, password FROM CONTACT WHERE username='%#' AND password='%#'",username,password];
sql = [querySQL UTF8String];
if (sqlite3_prepare_v2(database, sql, -1, &init_statement, NULL) != SQLITE_OK) {
NSAssert1(0, #"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
}
while (sqlite3_step(init_statement) == SQLITE_ROW)
{
NSLog(#"char sql = %s" ,sql);
dbusername = [NSString stringWithUTF8String:(char *)sqlite3_column_text(init_statement,0)];
dbpassword = [NSString stringWithUTF8String:(char *)sqlite3_column_text(init_statement,1)];
}
if ([dbusername isEqualToString:username] && [dbpassword isEqualToString:password])
{
//DBHelper.callingViewController = self;
[self.callingViewController addview];
}
else if (dbusername != username || dbpassword != password)
{
NSLog(#"dbusername is = %#" ,dbusername);
NSLog(#"dbpassword is = %#" ,dbpassword);
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Login Failed"
message:#"Username Or Password is not Correct"
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:#"OK ", nil];
[alert show];
[alert release];
}
sqlite3_reset(init_statement);
[self closeDatabase];
}
and also in DBhelper.h i define property for this
#property (strong) ViewController * callingViewController;
and within if condidtion in lognow method if password and username is succesully match i am calling this mathod in Viewcontroller.com file but am fail to call that
//ViewController.m
-(void) addview
{
DBHelper *f = [[DBHelper alloc] init];
f.callingViewController = self;
newview.center = CGPointMake(1000, 1000);
}
Though it's not wise to hold the viewController in the DBhelper(it breaks MVC), you could call your ViewController's method as your code but remember to set to pass your ViewController to the DBhelper. Maybe like this:
//ViewController.m
-(IBAction)login:(id)sender
{
DBHelper *objdb = [[DBHelper alloc] init];
[objdb loginnow:textname.text andpassword:textpassword.text viewController:self];
}
//DBHelper.m
-(void) loginnow:(NSString *) username andpassword:(NSString *)password viewController:(ViewController *)vc
{ ...
if ([dbusername isEqualToString:username] && [dbpassword isEqualToString:password])
{
[vc addview];
}
...
}
But in fact you should use a delegate (or block or notification, but delegate is the most case) here. Like this:
In DBHelper.h, before #interface, add
#class DBHelper;
#protocol DBHelperDelegate <NSObject>
-(void) DBHelp:(DBHelper *)helper didFinishedLoginSuc:(BOOL)suc;
#end
and between the #interface and #end tag, add(suppose you are not using ARC)
#property (nonatomic, assign) id delegate;
in the DBHelper.m, in the #implementation, add(suppose you are not using auto synthesize)
#synthesize delegate = _delegate;
Now, you can change the [self.callingViewController addview]; to
if (self.delegate && [self.delegate responseToSelector:#selector(DBHelp:didFinishedLoginSuc:)]) {
[self.delegate DBHelp:self didFinishedLoginSuc:YES];
}
Now you get a delegate prepared for every view controller which obey the DBHelperDelegate.
In your ViewController.h, tell the compiler that it obey the DBHelperDelegate by add behind the class declare:
#interface ViewController:UIViewController<DBHelperDelegate>
and change the addView method name to
-(void) DBHelp:(DBHelper *)helper didFinishedLoginSuc:(BOOL)suc
At last, when you click the button, set self as the objdb's delegate
-(IBAction)login:(id)sender
{
DBHelper *objdb = [[DBHelper alloc] init];
objdb.delegate = self;
[objdb loginnow:textname.text andpassword:textpassword.text];
}
Now, when you login successfully, -(void) DBHelp:(DBHelper *)helper didFinishedLoginSuc:(BOOL)suc in ViewController.m will be called and you can deal with your view.
Remember to set the delegate to nil when your viewController gets dealloc, or you will expect an memory error. Be careful.
So I'm trying to access the variable 'username' from another class and append it to a URL as a string. I'm getting the error "No known class method for selector 'myStaticUsername'" and don't really know how to solve it. Any help would be appreciated.
FirstViewController.h
+(NSString *) username;
FirstViewController.m
static NSString *myStaticUsername = nil;
#implementation FirstViewController
+(NSString *) username{
return myStaticUsername;
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
NSLog(#"Cancel Tapped.");
}
else if (buttonIndex == 1) {
myStaticUsername= Textbox.text;
NSLog(myStaticUsername);
}
My ViewController.m class where I'm trying to access it:
- (void)viewDidLoad
{
NSString *email = [FirstViewController myStaticUsername];
NSString *website =[NSString stringWithFormat:#"http://www.nameofwebsite?un=:%#", email]; //append the username right here
Thanks.
In your viewDidLoad you need to change this:
NSString *email = [FirstViewController myStaticUsername];
to this:
NSString *email = [FirstViewController username];
myStaticUsername is the name of your static NSString, but the name of the class method you wrote to access it is username.
I have an NSString, testString which is set to a value in my app. Then as a response to a button press in UIAlertView I have the following code:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
NSLog(#"String: %#", testString);
}
}
But for sme reason, this always causes the app to crash. I can't seem to figure out why.
Probably you create your string with one of convenience methods and don't retain it, so when it comes to alert's clickedButtonAtIndex it's already autoreleased.
You should define it as
#property (nonatomic, retain) NSString *testString;
In implementation:
#synthesize testString;
On creating:
self.testString = [NSString stringWithFormat:#"%#", #"My test string"];
and [testString release]; on dealloc.
Then when you use it in clickedButtonAtIndex you can be sure your testString has a right value
This is my code:
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
NSLog(#"location for url1 B %#", locationForURL1);
if ((alertView.tag <= 3) && (alertView.tag >= 1)) {
if (buttonIndex == 1) {
NSLog(#"location for url1 %#", locationForURL1);
The locationForURL1 had an entry in it in the rest of the code up until that point, but it crahes at the first NSLog here.
So i added nszombieenabled and got message sent to deallocated instance 0x508eda0. How do i use this to find out my problem? I've heard people saying put it in the init method, which confused me as i can't find an init method. I've never done debugging like this before.
EDIT:
I am allocating it like this:
#interface RewriteViewController : UIViewController <MPMediaPickerControllerDelegate> {
NSString *locationForURL1;
}
#property (nonatomic,retain) NSString *locationForURL1;
I think it's something to do with the self.VARIABLE thing, but i can never figure out when i'm meant to put the self. and if i'm meant to put something else instead.
This is all the references i have to locationForURL1 in the .m file:
#synthesize locationForURL1;
-(void)getWeatherLocation {
if (currentResult == 1) {
self.locationForURL1 = locationTown;
locationForURL1 = [locationForURL1 stringByAppendingString:#","];
locationForURL1 = [locationForURL1 stringByAppendingString:locationCountry];
}
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if ((alertView.tag <= 3) && (alertView.tag >= 1)) {
if (buttonIndex == 1) {
NSLog(#"location for url1 %#", self.locationForURL1);
self.weatherFullURL = [self.weatherFullURL stringByAppendingString:self.locationForURL1];
}
}
}
-(void)dealloc {
[locationForURL1 release];
[super dealloc];
}
self.locationForURL1 = locationTown;
locationForURL1 = [locationForURL1 stringByAppendingString:#","];
locationForURL1 = [locationForURL1 stringByAppendingString:locationCountry];
You are retaining locationTown by using self.locationForURL1, then immediately overwriting that assignment with two autoreleased objects. So, you are leaking one object and then your crash happens when the autorelease pool reaps the result of stringByAppendingString:.
http://www.markj.net/iphone-memory-debug-nszombie/
You must not be retaining locationForURL1 where ever you are creating it. I would suggest adding it as a property to your class:
#interface YourClass : UIViewController {
NSString *locationForURL1;
}
#property (nonatomic, copy) NSString *locationForURL1;
Then in your viewDidLoad (or where ever you are creating that string), do something like:
NSString *location = [[NSString alloc] initWith....];
self.locationForURL1 = location;
[location release];
Then in your -alertView:clickedButtonAtIndex: method, just refer to it as self.locationForURL1 and you should be fine.
I'm really pulling my hair out, this must be a simple problem, but I just can't see it.
I'm just trying to assign a value to a variable from a text field.
In my h file I have
NSString *currentPass;
#property (nonatomic, retain) NSString *currentPass;
My m file.
#synthesize currentPass;
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:
(NSInteger)buttonIndex{
if (alertView.tag == AlertPasswordAsk) {
UITextField* theTextField = ((UITextField*)[alertView viewWithTag: 5]);
currentPass = [NSString stringWithFormat:#"%#", theTextField.text];
if ([theTextField isEditing]) {
[theTextField resignFirstResponder];
}
}
}
- (void)alertView:(UIAlertView *)alertView
didDismissWithButtonIndex:(NSInteger)buttonIndex{
NSLog(#"didDismissWithButtonIndex tag=%i", alertView.tag);
if (alertView.tag == AlertPasswordAsk) {
if(buttonIndex == 1){
NSUserDefaults *myDefaults = [NSUserDefaults standardUserDefaults];
NSString *strPassword = [NSString alloc];
strPassword = [myDefaults stringForKey:#"pass"];
// ######### ERROR OCCURS HERE #########
NSLog(#"currentPass=%# strPassword=%#", currentPass, strPassword);
if (![currentPass isEqualToString:strPassword]) {
[6337:207] didDismissWithButtonIndex tag=10
Current language: auto; currently objective-c
(gdb) continue
Program received signal: “EXC_BAD_ACCESS”.
(gdb) bt
#0 0x02894903 in objc_msgSend ()
#1 0x00000000 in ?? ()
You need to retain the object you assign to currentPass:
self.currentPass = [NSString stringWithFormat:#"%#", theTextField.text];
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:
(NSInteger)buttonIndex{
if (alertView.tag == AlertPasswordAsk) {
UITextField* theTextField = ((UITextField*)[alertView viewWithTag: 5]);
//assigning to member variable will not retain your object.
// current address is just pointing to auto released object not retaining it.
// currentPass = [NSString stringWithFormat:#"%#", theTextField.text];
// use currentPass as with accessor:
self.currentPass = [NSString stringWithFormat:#"%#", theTextField.text];
if ([theTextField isEditing]) {
[theTextField resignFirstResponder];
}
}
}