I've been going around and around, I've been trying to use this example but running into trouble in the delegate method. I'm trying to figure out how to close this out. Looks like I've got a lot set correctly but need help on final step:
I'm getting a -[ThirdTab apiFinished:]: unrecognized selector sent to instance.
On line two of the WebServiceAPI.m : the self.aDelegate =aDelegate is giving me an error:
2) Local declaration of aDelegate hides instance variable.
This is my first go around with using delegates like this an can't figure out this error.
Thanks.
This is in my ThirdTab UITableViewController:
-(void)viewDidLoad {
[super viewDidLoad];
WebServiceAPI *api = [[WebServiceAPI alloc] init];;
api.delegate =self;
[api DataRequest:data3 delegate:self];
// this is where I'm trying to connect data3 to my tableview.
self.tableDataSource3 = [data3 objectForKey:#"Rows"];
self.webApi = api;
[api release];
This is the WebServiceAPI.h:
#import <UIKit/UIKit.h>
#class WebServiceAPI;
#protocol WebServiceAPIDelegate;
#interface WebServiceAPI : NSObject
{
id<WebServiceAPIDelegate>aDelegate;
NSDictionary *data3;
NSArray *rowsArrayFamily;
NSMutableData *receivedData;
NSString *jsonreturnFF;
}
#property (nonatomic, assign) id<WebServiceAPIDelegate>aDelegate;
#property (nonatomic, retain) NSDictionary *data3;
#property (retain,nonatomic) NSArray *rowsArrayFamily;
#property (nonatomic, retain) NSMutableData *receivedData;
#property (nonatomic, retain) NSString *jsonreturnFF;
- (void) DataRequest: (id) aDelegate;
#end
#protocol WebServiceAPIDelegate
#required
-(void)apiFinished:(WebServiceAPI*)api;
-(void)api:(WebServiceAPI*)api failedWithError:(NSError*)error;
#end
Here is the WebServiceAPI.m where I'm having the issue:
- (void) DataRequest:data3 delegate:(id) aDelegate; {
self.aDelegate = aDelegate;
NSUserDefaults *defaultsF = [NSUserDefaults standardUserDefaults];
NSString *useridFF = [defaultsF objectForKey:kUseridKey];
NSString *urlstrF = [[NSString alloc] initWithFormat:#"http://www.~.php?userid=%#",useridFF];
NSURLRequest *req3 =[NSURLRequest requestWithURL:[NSURL URLWithString:urlstrF]];
NSURLConnection *conn3 = [[NSURLConnection alloc] initWithRequest:req3 delegate:self];
NSMutableData *data =[[NSMutableData alloc] init];
self.receivedData = data;
// self.connection = conn3;
}
Your WebService.h declares a property:
#property (nonatomic, assign) id<WebServiceAPIDelegate>aDelegate;
Your WebService.m uses a different property:
self.delegate = aDelegate;
You can either change the name of the property to delegate in WebService.h, or use the current name of the property in WebService.m.
Related
Starting over. I am fairly new to objective C. I have created the following class and I can't figure out how to initialize the array.
Can anyone provide any guidance on how to initialize the NSArray?
StatusPost.m
#import "StatusPost.h"
#implementation StatusPost
#synthesize messageId, fromName, friendId, message, choice2, choice3, choice4, picture, fbImage, commentCount, commentArray;
-(id)initWithMessageId:(NSString*) rMessageId
fromName:(NSString*) rFromName
friendId:(NSString*) rFriendId
message:(NSString*) rMessage
choice2:(NSString*) rChoice2
choice3:(NSString*) rChoice3
choice4:(NSString*) rChoice4
picture:(NSString *) rPicture
fbImage:(UIImage *)rfbImage
commentCount:(NSString*) rCommentCount
commentArray:(NSArray*) rCommentArray
{
if (self = [super init]) {
commentArray = [NSArray new];
self.messageId = rMessageId;
self.fromName = rFromName;
self.friendId = rFriendId;
self.message = rMessage;
self.choice2 = rChoice2;
self.choice3 = rChoice3;
self.choice4 = rChoice4;
self.picture = rPicture;
self.fbImage = rfbImage;
self.commentCount = rCommentCount;
self.commentArray = rCommentArray;
}
return self;
}
- (void)dealloc {
[messageId release];
[fromName release];
[friendId release];
[message release];
[picture release];
[fbImage release];
[commentCount release];
[commentArray release];
[super dealloc];
}
#end
StatusPost.h:
#import
#interface StatusPost : NSObject {
NSString* messageId;
NSString* fromName;
NSString* friendId;
NSString* message;
NSString* choice2;
NSString* choice3;
NSString* choice4;
NSString* picture;
UIImage* fbImage;
NSString* commentCount;
NSArray* commentArray;
}
#property (nonatomic, retain) NSString* messageId;
#property (nonatomic, retain) NSString* fromName;
#property (nonatomic, retain) NSString* friendId;
#property (nonatomic, retain) NSString* message;
#property (nonatomic, retain) NSString* choice2;
#property (nonatomic, retain) NSString* choice3;
#property (nonatomic, retain) NSString* choice4;
#property (nonatomic, retain) NSString* picture;
#property (nonatomic, retain) UIImage* fbImage;
#property (nonatomic, retain) NSString* commentCount;
#property (nonatomic, retain) NSArray* commentArray;
-(id)initWithMessageId:(NSString*) rMessageId
fromName:(NSString*) rFromName
friendId:(NSString*) rFriendId
message:(NSString*) rMessage
choice2:(NSString*) rChoice2
choice3:(NSString*) rChoice3
choice4:(NSString*) rChoice4
picture:(NSString*) rPicture
fbImage:(UIImage*) rfbImage
commentCount:(NSString*) rCommentCount
commentArray:(NSArray*) rCommentArray;
#end
It is likely that you aren't ever initializing the array, so when you try to add an object, you are just sending a message to nil. In the custom class's init method, add the line:
commentArray = [NSMutableArray new];
[NSArray new] is shorthand for [[NSArray alloc] init], so, technically speaking, that statement "inits" the NSArray.
However, your code looks a bit peculiar. You have the following statements in your init:
commentArray = [NSArray new];
self.commentArray = rCommentArray;
The first statement is setting the instance variable commentArray to the address of the newly alloced/inited NSArray while the second is setting the property commentArray to a parameter value. However, you have (through the #synthesize) made the instance variable commentArray the "backing store" for the property commentArray, so when you execute the second line the effect of the first line is overwritten (and the NSArray you created is "leaked").
(But if your real question is how to "load" an NSArray with values, you should ask that question -- and you'll get different answers.)
I have an NSString that as an instance variable within my appdelegate as below:
distributedLCAAppDelegate.h:
#class distributedLCAViewController;
#interface distributedLCAAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
distributedLCAViewController *viewController;
NSString *token;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet distributedLCAViewController *viewController;
#property (nonatomic, copy) NSString *token;
#end
section from distributedLCAAppDelegate.m:
#implementation distributedLCAAppDelegate
#synthesize window;
#synthesize viewController;
#synthesize token;
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
token = [NSString stringWithFormat:#"%#",deviceToken];
token = [token stringByReplacingOccurrencesOfString:#" " withString:#""];
token = [token substringWithRange:NSMakeRange(1, [token length]-2)];
}
I need to be able to use this token variable within the view controller. Currently this is what I have:
section from within distributedLCAViewController.m:
- (IBAction)switchWasActivated:(id)sender
{
NSString *token2 = [[[distributedLCAAppDelegate alloc] token] autorelease];
}
However, token2 = "invalid cfstringref".
I initially tried declaring a public method called getToken, which just returned token. But I was getting the same problem in that case as well.
Any help would be appreciated!
Try this : (UPDATED) (fixed)
NSString* token2 = ((distributedLCAAppDelegate*)[[UIApplication sharedApplication] delegate]).token;
Try following -
- (IBAction)switchWasActivated:(id)sender {
distributedLCAAppDelegate *delegate = (distributedLCAAppDelegate *) [[UIApplication sharedApplication] delegate];
NSString *token2 = delegate.token;
}
Can you check the Files' Owner in "MainWindow.xib" if its delegate outlet is set to your distributedLCAAppDelegate? Just Ctrl-click on the yellow box-icon in Interface Builder.
distributedLCAAppDelegate* delegateobj = [(distributedLCAAppDelegate*)[UIApplication sharedApplication] delegate];
NSString *token_ = delegateobj.token;
NSLog(#"token_ :%#",token_);
Try This , it should work
i want to send data between views, but i get an error: unrecognized selector....
and the in the debugger, the variable mystring is a NSCFNumber ("at this time") instead of NSString...
allergy_appAppDelegate.h
#import <UIKit/UIKit.h>
#interface allergy_appAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
UIWindow *window;
UITabBarController *tabBarController;
NSMutableArray *result_array;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#property (copy , readwrite) NSMutableArray *result_array;
#end
viewcontroller.m
allergy_appAppDelegate *dataCenter = (allergy_appAppDelegate *)[[UIApplication sharedApplication]delegate];
dataCenter.result_array = [[NSMutableArray alloc] initWithArray:Parser_result];
result.m
allergy_appAppDelegate *dataCenter = (allergy_appAppDelegate*)[[UIApplication sharedApplication]delegate];
show_user_array = [[NSMutableArray alloc] initWithArray: dataCenter.result_array]
for (NSString *mystring in show_user_array) {
textView.text = [[textView text] stringByAppendingString:#"\n"];
textView.text = [[textView text] stringByAppendingString:mystring];
}
Instance variables should be camel-cased, not have _. I.e. result_array should be resultArray. Classes start with capital letters.
Are you sure your result array is full of instances of NSString or NSNumber (or whatever you need)?
Given that you are leaking the array here...
dataCenter.result_array = [[NSMutableArray alloc] initWithArray:Parser_result];
... it is unlikely that this is an over-release problem. Note also that copy with NSMutableArray won't do what you want (the compiler should flag it, but doesn't). -copy always returns an immutable copy of an instance of a class cluster.
I am currently building an app for the iPhone and cannot figure out why I keep getting a memory leak to appear in the Leaks Instrument tool.
Here is the code and I have added comments to two places of where it is happening.
NSString *pathname = [[NSBundle mainBundle] pathForResource:self.toUseFile ofType:#"txt" inDirectory:#"/"];
//Line below causes a leak
self.rawCrayons = [[NSString stringWithContentsOfFile:pathname encoding:NSUTF8StringEncoding error:nil] componentsSeparatedByString:#"\n"];
self.sectionArray = [NSMutableArray array];
for (int i = 0; i < 26; i++) [self.sectionArray addObject:[NSMutableArray array]];
for(int i=0; i<self.rawCrayons.count; i++)
{
self.string = [self.rawCrayons objectAtIndex:i];
NSUInteger firstLetter = [ALPHA rangeOfString:[string substringToIndex:1]].location;
if (firstLetter != NSNotFound)
{
NSInteger audio = AUDIONUM(self.string);
NSInteger pictures = PICTURESNUM(self.string);
NSInteger videos = VIDEOSNUM(self.string);
//Line below causes a leak
[[self.sectionArray objectAtIndex:firstLetter] addObject:[[Term alloc] initToCall:NAME(self.string):audio:pictures:videos]];
}
[self.string release];
}
Thanks in advance!
Edit
Here are my property declarations.
#property (nonatomic, retain) NSArray *filteredArray;
#property (nonatomic, retain) NSMutableArray *sectionArray;
#property (nonatomic, retain) UISearchBar *searchBar;
#property (nonatomic, retain) UISearchDisplayController *searchDC;
#property (nonatomic, retain) NSString *toUseFile;
#property (nonatomic, retain) NSArray *rawCrayons;
#property (nonatomic, retain) NSString *string;
#property (nonatomic, retain) TermViewController *childController;
Here are the leaks that are occurring after follow Nick Weaver's fixes.
Here is an expanded version of one of the NSCFString.
And another image.
Image with the Responsible Caller:
Also, because this may be useful, here are the properties for Term:
#property (nonatomic, retain) NSString *name;
#property (nonatomic) NSInteger numberAudio;
#property (nonatomic) NSInteger numberPictures;
#property (nonatomic) NSInteger numberVideos;
And the implementation:
#implementation Term
#synthesize name, numberAudio, numberPictures, numberVideos;
- (Term*)initToCall:(NSString*) toSetName:(NSInteger) audio:(NSInteger) pictures:(NSInteger) videos
{
self.name = [toSetName retain];
self.numberAudio = audio;
self.numberPictures = pictures;
self.numberVideos = videos;
return self;
}
- (NSString*)getName
{
return [[name retain] autorelease];
}
-(void)dealloc
{
[name release];
[super dealloc];
}
#end
Ok, try this changed Version of Temp. I've deleted the getter because you have already one by synthesizing. You cann use the getter like this for name:
term.name
The problem was how you set the name: you want a copy of the name and setting it with the synthesized setter without calling a retain should do the trick. You could, of course, have set it with the retained property of name but you should have left out retain, like this self.name = toSetName;. The setter will retain it for you.
#property (nonatomic, copy) NSString *name;
#property (nonatomic) NSInteger numberAudio;
#property (nonatomic) NSInteger numberPictures;
#property (nonatomic) NSInteger numberVideos;
#implementation Term
#synthesize name, numberAudio, numberPictures, numberVideos;
- (Term*)initToCall:(NSString*) toSetName:(NSInteger) audio:(NSInteger) pictures:(NSInteger) videos
{
self.name = toSetName;
self.numberAudio = audio;
self.numberPictures = pictures;
self.numberVideos = videos;
return self;
}
-(void)dealloc
{
[name release];
[super dealloc];
}
Adding an object to an array will retain the instance, so the retain is 2 because you call
[[Term alloc] initToCall..
Do something like
Term *term = [[Term alloc] initToCall..];
[theArray addObject:term];
[term release];
1. See the arrow in the first line in the address column? Click it!
2. After clicking :)
Hard to tell you why the first one is leaking, because we don't know what the property is declared as. Is it retain? copy? assign? what?
The last one is fairly self explanatory though, you're taking ownership of a Term object, and not releasing it when it's added. addObject: retains its argument, meaning if you don't need that Term anymore, you need to give up ownership. I.e., pass -autorelease to the result of your initToCall:::: (which btw is a very bad name for a method)
Change:
[[self.sectionArray objectAtIndex:firstLetter] addObject:[[Term alloc] initToCall:NAME(self.string):audio:pictures:videos]];
to:
Term *tempTerm = [[Term alloc] initToCall:NAME(self.string):audio:pictures:videos];
[[self.sectionArray objectAtIndex:firstLetter] addObject:tempTerm];
[tempTerm release];
By alloc'ing an object you are responsible for it's release.
I've been trying to figure this out but I can't figure out what I'm doing wrong.
I wrote a class and whenever I try to initialize it, I get a EXC_BAD_ACCESS error. I can't even step into the initialization.
Anyone have any idea what I'm doing wrong?
User *myUser = [myUser init];
.h file:
#import <Foundation/Foundation.h>
#interface User : NSObject {
long rowId;
NSString *email;
NSString *password;
NSString *fileVersion;
}
#property long rowId;
#property (assign) NSString *email;
#property (assign) NSString *password;
#property (assign) NSString *fileVersion;
#end
.m file
#import "User.h"
#implementation User
#synthesize rowId, email, password, fileVersion;
-(id)init {
self = [super init];
return self;
}
#end
You have to actually allocate the object:
User *myUser = [[User alloc] init];
Don't forget to release it when you're done using it.