As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
I created a getter to get the content of a variable, but it doesn't works.
Here the code:
-(void)documentURLReceived:(NSURL *)url{
_getUrl = [[NSURL alloc] init];
_getUrl = url;
NSLog(#"Result: %#", _getUrl);
}
-(void)getUrl{
NSLog(#"getUrl: %#", _getUrl);
}
Here the result in the consol:
Result: http://www.google.com
getUrl : (null)
I don't understand why!
Here my property:
#property (strong, nonatomic) NSURL *getUrl;
Thanks for your help :)
If you are using ARC and the latest Xcode - get rid of the getURL method - you should not be overwriting this unless you need to do custom logic, furthermore, your getURL method returns nothing and is a void method - so the variable is most likely set but your method is overwriting the automatically generated getter and is returning nothing.
Did a test in Xcode
In header file I have:
#property (nonatomic, strong) NSURL *getURL;
and then in implementation file I have:
- (void)documentURLReceived:(NSURL *)url
{
_getURL = url;
NSLog(#"%#",_getURL);
}
which outputs:
2013-04-04 23:29:27.681 VitalityDesignTestSuite[90518:c07]
http://www.google.com
okie dokie I wrote you a sample:
http://bit.ly/10yWb36
to use those you can go:
MyViewController *mvc = [[MyViewController alloc] initWithNibName:#"MyViewController" bundle:nil];
//Now you can set the myURL variable directly
[mvc setMyURL:[NSURL URLWithString:#"http://www.google.com"]];
NSLog(#"Direct Setting: %#",mvc.myURL);
//OR you can call the method your wrote
[mvc documentDidReceiveURL:[NSURL URLWithString:#"http://www.google.com"]];
NSLog(#"Selector Setting: %#",mvc.myURL);
that outputs:
2013-04-04 23:39:09.407 VitalityDesign[92197:c07] Direct Setting: http://www.google.com
2013-04-04 23:39:09.408 VitalityDesign[92197:c07] Selector Setting: http://www.google.com
hope this helps
First of all are you getting anything in url?
If No, -> Work over it
If yes then, try to do following:
_getUrl = [[NSURL alloc] init];
_getUrl = url;
[_getUrl retain];
NSLog(#"Result: %#", _getUrl);
Enjoy Programming!
Related
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Two of my programs available in the AppStore for months and running without any problems on iOS3 and iOS4 are not compatible with iOS5.
It seems to me that Apple has changed some things to make the life of developers a little bit harder.
One of the problems is this:
- (BOOL) webView: (UIWebView *) webView shouldStartLoadWithRequest:(NSURLRequest *) request navigationType: (UIWebViewNavigationType) navigationType {
// Only do something if a link has been clicked
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
NSString *link = [[request URL] absoluteString];
if ([link hasPrefix:#"playSound:"]) {
[PlayAudio playAudio: [link substringFromIndex:10]];
return NO;
}
}
return YES;
}
The line that make the problem is
NSString *link = [[request URL] absoluteString];
Before I got an unmodified copy of the clicked link. In iOS3 and iOS4 it is still the same. But on iOS5 it is converted to lowercase only.
The next Line
if ([link hasPrefix:#"playSound:"]) {
never becomes true. So I had to change the code to
- (BOOL) webView: (UIWebView *) webView shouldStartLoadWithRequest:(NSURLRequest *) request navigationType: (UIWebViewNavigationType) navigationType {
// Only do something if a link has been clicked
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
NSString *link = [[[request URL] absoluteString] lowercaseString];
if ([link hasPrefix:#"playsound:"]) {
[PlayAudio playAudio: [link substringFromIndex:10]];
return NO;
}
}
return YES;
}
Now I'm expecting lowercase on all versions of iOS and therefore compare with a lowercase string.
What do you think: Are changes like this on a new iOS version neccessary?
I'm using this fork of AudioStreamer to stream audio.
In a view controller I have an AudioStreamer as a property:
#property (nonatomic, retain) AudioStreamer *streamer
When the view controller loads I start a stream like this:
self.streamer = [[AudioStreamer alloc] initWithURL:[NSURL URLWithString:preset.url]];
And to stop the stream, release it, and start a new stream I'm doing this:
[streamer stop];
[streamer release];
self.streamer = nil;
self.streamer = [[AudioStreamer alloc] initWithURL:[NSURL URLWithString:preset.url]];
This doesn't work because in the initWithURL: method, there's a check to see if (self != nil) and that check fails.
Would anyone be able to clarify why this isn't working?
Thanks.
EDIT: It was actually some issues with my project that was causing weird issues. However, I marked an answer as correct because it had some good memory tips that also helped.
You are overretaining the streamer instance by setting it with the dot syntax and using alloc.
The synthesized setter will retain it once and alloc the second time, you should add an autorelease:
self.streamer = [[[AudioStreamer alloc] initWithURL:[NSURL URLWithString:preset.url]] autorelease];
This line:
self.streamer = [[AudioStreamer alloc] initWithURL:[NSURL URLWithString:preset.url]];
Will automatically release the previously assigned instance for you. So you don't have to call
[streamer release];
self.streamer = nil;
before it.
However you should do
[streamer release];
in your dealloc method.
First of all, you're double-releasing streamer without intending to.
[streamer release]; // Releases the ivar, but doesn't set it to nil.
self.streamer = nil; // This is a property access, which releases the old
// value (again) before setting to nil.
And your assignment in the final line is leaking a reference (you're allocing, and then assigning to a retain property).
You're sort of mixing access metaphors. If you have the property, then use it exclusively:
[self.streamer stop];
self.streamer = [[[AudioStreamer alloc] initWithURL:[NSURL URLWithString:preset.url]] autorelease];
All that said, a failed self != nil check isn't necessarily explained by this, but it might be, depending on what AudioStreamer is doing for its internal object management.
I'm making an application in Xcode, and running into some problems. I'm using the GameKit framework to allow for bluetooth communication between two iOS devices. The application is setup so that one of the devices is the "master" and the other is the "slave," changing it's screen content based on data received from the "master" device. The user can select whether to be the master or the slave, and when that choice is made, the other device automatically becomes the opposite role. This is all done in one view controller class. When a role is chosen, a subview is added to the baseViewController.
What my problem is, is that when the subview that is added, I would like to be able to send data using the methods in the baseViewController class. With the current setup, the device invoking the action becomeMaster:sender crashes.
What I've tried so far is,
BaseViewController:
-(IBAction)becomeMaster:(id)sender {
[self dataToSend:#"slave"]; //tells peer device to become slave, since this device is master
masterViewController = [[MasterViewController alloc] initWithNibName:#"MasterViewController" bundle:nil];
[masterViewController setBaseViewController:self];
[self.view addSubview:masterViewController.view];
}
-(void)dataToSend:(NSString *)direction {
//—-convert an NSString object to NSData—-
NSData* data;
NSString *str = [NSString stringWithString:direction];
data = [str dataUsingEncoding: NSASCIIStringEncoding];
[self mySendDataToPeers:data];
}
-(void)dataToSend:(NSString *)direction {
//—-convert an NSString object to NSData—-
NSData* data;
NSString *str = [NSString stringWithString:direction];
data = [str dataUsingEncoding: NSASCIIStringEncoding];
[self mySendDataToPeers:data];
}
//----------------------------------------------------------------------------//
- (void)receiveData:(NSData *)data fromPeer:(NSString *)peer inSession:(GKSession *)session context:(void *)context {
//—-convert the NSData to NSString—-
NSString* str;
str = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
[self useReceivedData:str];
[str release];
}
-(void)useReceivedData:(NSString *)str {
if ([str isEqualToString:#"forward"]) {
[slaveViewController.view setBackgroundColor:[UIColor blackColor]];
}
}
MasterViewController:
-(void)setBaseViewController:(BaseViewController *)bvc {
baseViewController = bvc;
}
-(IBAction)goForward:(id)sender {
actionLabel.text = #"goingForward";
[baseViewController dataToSend:#"forward"];
}
Most of that code is part of the standard Apple documentation/examples, but I included it for understanding the flow of logic.
I believe the problem originates to with the becomeMaster:sender and setBaseViewController:bvc methods. Could anyone help fix? Thanks so much!
What kind of crash are you getting? EXC_BAD_ACCESS? Try turning on NSZombieEnabled in your executable's arguments. It's difficult to say what could be causing the crash, but you might try changing your setBaseViewController: implementation to this:
-(void)setBaseViewController:(BaseViewController *)bvc {
[self willChangeValueForKey:#"baseViewController"];
[baseViewController autorelease]
baseViewController = [bvc retain];
[self didChangeValueForKey:#"baseViewController"];
}
And add [baseViewController release]; to MasterViewController's -dealloc method.
Keep in mind that it's not entirely necessary to have a custom setter for baseViewController. If you have the following property declaration in your header file:
#property (nonatomic, retain) BaseViewController *baseViewController;
And you use #synthesize baseViewController, the -setBaseViewController: method is already generated for you, with key-value observing support built in. If you aren't familiar with Objective-C 2.0 properties, I suggest reading Apple's documentation.
I'm trying to share data between various viewControllers, I'm using a property declared in the appDelegate. I set the property in my first viewController and when I print out the contents, everything looks fine, but after I call a custom class method, the property gets set to some random value that seems to change every time I run the app. See code below:
appDelegate .h
NSDate *lastUpdated;
#property (nonatomic, retain) NSDate *lastUpdated;
viewController .m
AppDelegateClassName *appDelegate = (AppDelegateClassName *)[[UIApplication sharedApplication] delegate];
[appDelegate setLastUpdated:[NSDate date]];
After I set the property, I then call the following custom class method with a reference to the viewController as a parameter:
viewController .m
ForceData *forceData = [[ForceData alloc] init];
[forceData queryServiceWithParent:self];
If I try and display the contents of the appDelegate property within my custom class, it returns a random value. Once the custom class returns to the viewController, the appDelegate property stays as the random value.
I can't see what's going wrong. Can anyone help?
Thanks.
UPDATE
Here is the code within the queryServiceWithParent method:
- (void)queryServiceWithParent:(UIViewController *)controller {
viewController = (ForcesTableViewController *)controller;
responseData = [[NSMutableData data] retain];
NSString *url = [NSString stringWithFormat:#"http://example.com"];
theURL = [[NSURL URLWithString:url] retain];
NSURLRequest *request = [NSURLRequest requestWithURL:theURL];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
I'm still having this problem so any help is much appreciated.
UPDATE:
I've spent some more time looking at this and I can display the contents of lastUpdated anywhere within the queryServiceWithParent (just above) and it displays fine. But if I display the same property in the connectionDidFinishLoading, it's reset. Very stuck with this one!
The way this sounds to me is that your NSDate property is autoreleased at some point, even though your memory management sounds fine the way you describe it.
Can you try to add an extra retain to your NSDate, as in:
appDelegate.lastUpdated = [[NSDate date] retain]
If that helps than we need more information about your code to find out where your memory management has errors. i.e. the complete header and main file of your appDelegate and viewController.
From a related thread, how should I have known the "mailString" below was already autoreleased?
//
+ (void) sendEmail:(NSString *) subject withBody:(NSString *)body {
NSString *mailString = [NSString stringWithFormat:#"mailto:?#&subject=%#&body=%#",
[subject stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding],
[body stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:mailString]];
[mailString autorelease];
}
stringWithFormat: is a convenience function that returns an autoreleased object.
I cannot recomment the Memory Management Guide highly enough. It really is worth reading, probably more than once.
since mailString is not created by the [[NSString alloc] init]; idiom it does need to be released.
You do not know that the object has been autoreleased.
All you know is that it is not your responsibility to release it.
You know that because it was returned to you from a method whose name did not begin with 'alloc', 'new', or contain 'copy', and you have never called 'retain' against it.
Reiterating what Eiko said - read Apples Memory Management Guide - it is very clear on this topic.