Objective-C Xcode: Tableview detailitem empty - iphone

I'm doing this tutorial (http://www.raywenderlich.com/1845/how-to-create-a-simple-iphone-app-tutorial-part-2) to get the hang of ios development, but now I'm stuck.
It's probably just a little thing, but when I get in my detailView's method 'setDetailItem', the newDetailItem variable is empty (see screenshot).
I have no idea why this is, but in the tutorial this seems to get automatically filled.
Why is it empty and how do I get the right detailItem?

I checked the tutorial and a sample code is provided by them.It works fine with the memory.It is a setter method which is called when you provide the value like this
DetailViewController *detailController =segue.destinationViewController;
ScaryBugDoc *bug = [self.bugs objectAtIndex:self.tableView.indexPathForSelectedRow.row];
detailController.detailItem = bug;
check weather you are passing in valid memory value (here bug).if you give it nil then yeah there may be no memory

Related

Swift View Controller Downcasting

I thought the following would populate my home variable with my HomeViewController
var home = self.parentViewController!.parentViewController! as HomeViewController;
Instead I get the following compile error 'Use of undeclared type HomeViewController' although it definitely exists and appears in the auto complete popup.
Often XCode6 displays the wrong error message. Is this an instance variable? It may be that parentViewController isn't set at init time (the fact that it's an implicitly unwrapped optional strongly suggests this). If this is in a function, I'd do this in an if let statement to give us a better sense of what's going on. Something like:
if let homeVC = self.parentViewController?.parentViewController as? HomeViewController {
self.home = homeVC
}
This would give us at least a better opportunity to debug. Two !s in a row maybe means you're not being totally respectful of what those declarations are trying to tell you.
The cause of this error was actually coming from a bug in xcode 6 rather than any kind of syntax error. It was related to this: Xcode 6 Strange Bug: Unknown class in Interface Builder file
I was able to fix this by clearing the projects derived data and build and restarting my machine.
I had faced the same problem while doing an unwind segue and trying to downcast the sourceviewcontroller. I bang my head for more than 30mins and then I realized it was fairly simple and bit crazy, I had all my files except this viewcontroller added to the Tests target and after adding this viewcontroller to the Tests target, everything worked Tada!! I m saved.

Setter failing selectively in NSManagedObject

I have a NSManagedObject which I'm trying to instantiate with given values. I access the setters like so:
object.couchID = (NSString *)[dictObject objectForKey:#"_id"];
...and this works fine on my machine, but my partner gets this error when he runs it on his machine:
'-[NSCFString type]: unrecognized selector sent to instance 0x4e465e0'
About 90% of the setters (all formatted in the same way) work on my partner's machine, but a good 10% fail with that error. All of them work on my machine.
We're running the exact same code (according to SVN (yes, I know)), and fetching the same data from the same server, so everything seems like it should work.
We've checked the objects being passed, and they're the same. Commenting out the setter allows the code to get through to the next troublesome setter, but of course we need it to actually work. How else should we troubleshoot? Thanks in advance.
Update 1: Unlocked the Tumbleweed badge for that one... guess it's too sticky to touch? Any thoughts or guesses are welcome. And hey, you could earn 50 points.*
Update 2: the mixed-good-news is that checking out a fresh version from source control results in the same problem on my machine, so a) it's definitely something in the code, and b) I can more actively troubleshoot. Thanks for all your suggestions so far, I'm going to go through them all again.
I ran into something similar at work the other day. I suspect that one of you has a stale .momd file inside the app bundle, and that it's not being replaced when it gets upgraded. I suspect this is a bug in Xcode 4, though I haven't totally verified it yet. If your partner deletes the app completely and then installs the app, does the error go away?
You may need to create a temporary variable whose value is object cast to whatever the actual class is, e.g.
MyClass *c = (MyClass *)object; // if object is in fact a MyClass instance
c.couchID = (NSString *)[dictObject objectForKey:#"_id"];
I have seen cases where the compiler cannot make mental leap and realize that your attribute is the class you know it is. The solution for me in these cases has been to be more explicit. Does this make sense? It's worth a shot at least, no? :-)
if this code fails on your partner's machine:
someManagedObject.couchID = #"some hardcoded string";
seems like you have a dangling pointer: i would check that someManagedObject is properly retained and still a valid object when you try to call the -setCouchID method on it.
I have had nearly the same problem when trying to draw a CATiledLayer with data in NSManagedObjects. What should be a valid object barfs with an "unrecognised selector" exception
It nearly always happens because theres no retain on the object external to the point where you are trying to set or get the property. Being in a separate thread seemed to have a relationship too.
After fruitlessly trying to get round this with [NSManagedObjectContext lock] and retain on the context within the new thread I eventually just threw the contents of my fetch into a mutable set to try and keep a grip on it which seems to work on iOS but not on OS X so well.
So a couple of possibilities
Are you doing this not in the main
thread and does the MOC have a retain
within that thread. Check the docs
for [NSManagedObjectContext lock]. But essentially each thread working with the context needs its own retain on the context.
Try throwing it into a container
while you operate on it. Make it a
bit stickier. Sorry if that sounds
like voodoo but it is.

how to fault find if a delegate call is not being picked up in objective-c

Just implementing my first delegate in objective-C. I thought I had everything in place however the call from my AddController back to ListController isn't being picked up in the ListController.
Given that I'm not getting an exception, and that I can see that the code does get to the point in the AddController where it calls the delegate, are there any fault finding tips?
So for example:
given the "delegate" call (see below) did not throw an exception can I assume that my delegate declarations in the same file are OK?
"[delegate newItemController:self didFinishWithSave:YES];"
given the parent controller so to speak does have the delegate specified in the *.h definition (see below), then this does implied I've correctly implemented the method in the *.m file, noting I get no build errors?
#interface RootViewController : UITableViewController {
is there a known way for delegate calls to go missing without an exception if certain items don't like up (i.e. if there is what should I check for)
thanks
Most common error I've seen for a delegate method not being called is a nil delegate property. In other words, forgetting to specify who the delegate is?
As for debugging tips, anytime I've seen a problem where a delegate is not being called is to set breakpoints throughout the code and step through the code. Then you can see where things are going and what is or isn't being called.
Also, you mention exceptions a lot. Objective C prefers not to use exceptions as they are a relatively expensive call in the language (unlike say Java). Objective C can and does use exceptions but they are rare. You might want to "beaf up" your understanding of error handling in objective c.
Have you set your delegate variable like this in your AddController:
self.delegate = <instance of ListViewController>
If it has not been set, then the delegate would be nil and the method call to the nil would result in nothing. Otherwise, delegate calls wouldn't really go missing like that.
I didn't understand your second point though.

iPhone leak on this line, why?

I am getting a leak on this line and I'm not sure why...
weather.condition = [weather.condition lowercaseString];
weather is a NSMutableArray with a load of NSStrings in? Is there anything obviously wrong with this line or is it a bigger issue?
Thanks
One thing you have to learn about detecting memory leaks, is that leaks doesn't detect the line the leak occurs on per say, it detects where the object that is leaking was retained/copied/created. You need to look elsewhere for the actual leak, posting more code would be helpful. I'll update this answer if you do. Please comment below to indicate you've updated the answer with more code.
I remember i had this problem when i was using stringByReplacingOccurrencesOfString and i had to declare a new string to hold it in, rather than perform it on itself if that makes any sense!:)
If weather.condition is a synthesized retain property, then you could probably get away with that statement without a leak because the synthesized setCondition method will check to see if there is a value assigned to condition, and release it. If you wrote the setCondition method, you are responsible for managing the memory associated with condition.

Objective C: [MyObject alloc] now crashes under iOS SDK 4.1

I'm working on an existing, large-ish codebase, and after upgrading the iOS SDK to 4.1 I am now seeing very strange behaviour. The crux of the matter appears to be a particular class that will no longer alloc - it is throwing a bad access in obj_msgSend, and seems to be the Class object on the stack that objc_msgSend doesn't like - although it is not actually NULL.
The original failing line looked like this:-
tileProjection = [[RMFractalTileProjection alloc] initFromProjection:proj tileSideLength:sideLength maxZoom:18];
I deconstructed this to isolate the problem:-
RMFractalTileProjection *p = [RMFractalTileProjection alloc]; // <- this crashes
p = [p initFromProjection:proj tileSideLength:sideLength maxZoom:18];
tileProjection = p;
I then tried this:-
Class c = NSClassFromString(#"RMFractalTileProjection");
assert(c);
NSLog( #"RMFractalTileProjection class(ptr) %p", c ); // <- prints an address OK
NSLog( #"RMFractalTileProjection class(obj) %#", c ); // <- crashes
In the debugger it looks like the Class object is sensible, but NSLog crashes when it tries to print it.
One thing to note: the class in question is declared as below, and I'm not sure if the protocol is causing a problem. Because this particular part is a large chunk of open source code, it is very difficult to remove this protocol requirement to see if that makes a difference.
#interface RMFractalTileProjection : NSObject<RMMercatorToTileProjection>
{
...
}
Any help on this one greatly appreciated - it is a show stopper.
Thanks
This is not really an answer but some ideas to move forward.
The only causes that leap to mind at the moment are memory corruption and some sort of link issue. Perhaps you are linking two versions of the class somehow.
Assuming this is the class, there doesn't look to be anything wrong to make it crash in alloc. There's no +initialize or anything.
Questions I would be asking myself and trying to answer are:
what happens if I rename the class?
what happens if I create a new identical class with a different name?
the pointer that gets passed to obj_msgSend: is it reasonable? does it point to something that looks like a class?
do you ever subclass the class and do you use initialize on the subclass?
is the pointer always the same? If so you can watch what it points to and see if it changes during execution.
what happens if you send self to the class?
OK, finally found this. As Jeremy suggested, this turned out to be a regular memory stomper.
The difficulty I had finding it was that it wasn't the Class object itself that was getting stomped, but the class' metaclass structure - which is a normal Class object but one level up, referenced by the class 'isa' pointer. That's why the class looked OK to me when I inspected it in the debugger - I need to follow the isa pointer and dump memory at one level up to find this. Luckily for me, the class was only a subclass of NSObject - had it been deeply subclassed, this could have been much harder to find. I got my first clue after biting the bullet, reverse-engineering objc_msgSend, working out exactly what was on the stack frame, and following all the pointers. Yep, the hard way :)
Matt Gallaghar's post (and various others I found by following links) were invaluable in helping me through this maze - thanks guys!
Burned a lot of time on this one, but on the up side I learned a hell of a lot about Objective C internals during the past day and a half :)
Thanks for these suggestions JeremyP - it is always good to have fresh suggestions after you've been banging your head against the keyboard all day!
Your suggestion of creating an identical class with the same name appears to have fixed the problem. I have no idea why and I feel I need to understand what's going on here. You're right it sounds like some kind of linker issue, but I still have no idea what could cause such a serious runtime error and not even produce a warning at build time.
Re. the pointer, it does look reasonable, but something inside the class eventually gets dereferenced as a null pointer inside objc_msgSend. Occasionally, after I have changed the code and rebuilt, I get a null pointer instead. This behaviour obviously suggests something nondeterministic like a memory stomp.
I'll post my findings.