self.view removeFromSuperview crashes - objective-c

i hope this is my last question for a while, I open a xib file via:
Results1 *myView1 = [[Results1 alloc]initWithNibName:#"Results1" bundle:nil];
[self.view addSubview:myView1.view];
I have a button on the second xib file:
-(IBAction)Button1:(id)sender
{
[self.view removeFromSuperview];
}
It crashes every time:
0xecf09b: movl 8(%edx), %edi
I have the views linked
I am not sure if this is the problem:
#interface TestTypingToolViewController ()
{
NSString *iResults1;
NSString *iResults2;
NSString *iResults3;
NSString *iResults4;
NSString *iResults5;
NSString *Segment;
NSDictionary *ResultsData;
}
#end
Thanks for all your help, everyone!

The problem is I needed to turn off Automatic Reference Counting and everything worked.

It seems that you have got some issue with zombies, i.e., some object that is deallocated at some point but you try to access through some (dangling) reference. You could get more info about it by enabling zombies detection.
Actually, my guess is that you could fix this by storing Results1 *myView1 in a property of your class. Indeed, in your code, what happens is the myView1.view is retained by self.view; while myView1 is stored in a local variable, so the object (under ARC) should be deallocated when the variable is not used anymore. You have a mismatch here between the lifetimes of the two objects and this could lead to the crash.

ClassName.h
#property (nonatomic, strong) UIViewController *myView1;
ClassName.m
#synthersize myView1;
// in -(void)viewDidLoad
self.myView1 = [[Result1 alloc] init];
[self.view addSubview:self.myView1.view];

Related

NSMutableArray keeps returning null

I have declared a property NSMutableArray in the header file. Then I alloc, init it in the viewDidLoad method. But when I try to add an object to the array in a different method it keeps returning (null). Am I doing some obvious mistake? Please ask if you want to see some more code.
.h
#property (strong, nonatomic) NSMutableArray *myList;
.m
- (void)viewDidLoad
{
self.dataController = [[DataController alloc]init];
self.myList = [[NSMutableArray alloc] init];
[super viewDidLoad];
}
[...]
NSDictionary *myObject = [self.dataController.objectList objectAtIndex:r];
[[cell textLabel]setText:[myObject objectForKey:#"title"]];
[self.myList addObject:myObject];
NSLog(#"myList %#",self.myList);
NSLog(#"myObject %#",myObject);
The output prints myObject but self.myList keeps returning (null). Appreciate all help!
Edit: Fixed, thank you for your answers!
Not sure where you are using this array. If you have to use this array before viewDidLoad is called, you can do it as,
NSDictionary *myObject = [self.dataController.objectList objectAtIndex:r];
[[cell textLabel]setText:[myObject objectForKey:#"title"]];
if (!self.myList)
self.myList = [[NSMutableArray alloc] init];//for the first time, this will initialize
[self.myList addObject:myObject];
Since you are using [cell textLabel] I am assuming that you are doing this in one of the table view delegates. In that case check if you are setting self.myList = nil; any where in the class.
In your posted code i see no error.
Set a breakpoint and look if the code where you init the array is called first.
I bet that viewDidLoad hasn't been called yet when the NSLogs are execute.
To ensure that the array has been initialized, try putting the initialization in your init method.

Properly passing NSManagedObjects between views when using ARC? Memory warning & crash

Hi I have a nasty memory management issue under ARC and cannot figure out how to solve it. The problem stands like this, I have these objects:
ObjectManager - a singleton that does fetchRequests to core data and fetches one or more NSManagedObjects
UIViewControllerA - a view controller in which I have a button "PassManagedObject" and a property declared as below:
#property (strong, nonatomic) ManagedObject *objectForToday;
in viewDidLoad on UIViewControllerA, I call the method refreshDailyObject which does this:
self.objectForToday = nil;
self.objectForToday = [[ObjectManager sharedManager] getDailyObject];
if I tap the PassManagedObject button I create UIViewControllerB, pass the objectForToday to it and display it, see below
- (IBAction)passManagedObjectTapped:(id)sender {
UIViewControllerB *viewController = [[UIViewControllerB alloc] initWithNibName:#"UIViewControllerB"];
viewController.object = self.objectForToday;
[self.navigationController pushViewController:viewController animated:NO];
}
UIViewControllerB has a property declared like this:
#property (strong, nonatomic) ManagedObject *object;
and a button "Back" which does this:
- (IBAction)backAction:(id)sender {
self.object = nil;
[self.navigationController popViewControllerAnimated:NO];
}
Now the problem is this. If I tap continuously passManagedObjectTapped and then backAction, and again passManagedObjectTapped and again backAction and then again passManagedObjectTapped and automate this I'm getting eventually Received Memory Warning 1, and then crash.
The Instruments doesn't show any leaks but my memory allocation keeps slowly going up.
I am using ARC under iOS4.3 & iOS5. I've been struggling to figuring out what is wrong for a day now. Any help will be highly appreciated.
Thanks!
The self.object = nil; and self.objectForToday = nil; isn't necessary - ARC and the synthesized properties setters already take care of that.
It seems pretty likely that you have a circular reference somewhere. Do you have any situations where object A has a strong reference to object B and object B has a strong reference to object A?
If so, just change one of those references to weak instead (or assign if you want to support iOS 4.3).

Crash on NSMutableDictionary's setObject function

Here is my code:
NSLog(#"dictionaryPlayers=%#,%d",[dictionaryPlayers description],dictionaryPlayers.count);
[dictionaryPlayers setObject:#"test" forKey:#"test2"];
dictionaryPlayers is inited in this class's init function:
-(id)init{
...
dictionaryPlayers = [[NSMutableDictionary dictionaryWithCapacity:10]retain];
...
}
The program crashed:
Thread 1:Program received signal: "SIGABRT".
And in console:
2011-12-27 17:01:21.744 [25454:207] dictionaryPlayers={
},0
2011-12-27 17:01:21.745 [25454:207] -[__NSCFConstantString tick]: unrecognized selector sent to instance 0x199bcc
With the NSLog outputs, i think dictionaryPlayers is well inited. So I don't know why crashed...
The object on which you call tick: is not longer in memory and causes this crash. Try to see why this object is released.
It seems that this is not a local case, so did you make sure to synthesize it at the top? And declared it correctly in the header? Examples:
In header:
#property (nonatomic, strong) NSMutableDictionary *dictionaryPlayers;
in class:
#synthesize dictionaryPlayers = _dictionaryPlayers;
I removed
dictionaryPlayers = [NSMutableDictionary dictionaryWithCapacity:10];
from init(), and added
dictionaryPlayers = [[NSMutableDictionary alloc] init];
above my log statement. Still crash....
Then I removed
[dicTest setValue:#"Test" forKey:#"testKey"];
So there's only 2 lines left:
dictionaryPlayers = [[NSMutableDictionary alloc] init];
NSLog(#"dictionaryPlayers=%#,%d",[dictionaryPlayers description],dictionaryPlayers.count);
It didn't crash. So, it seems the setValue line really is the problem.
You don't need to call retain on the object in your init statement. Also just for giggles try:
dictionaryPlayers = [[NSMutableDictionary alloc] init];
instead of
dictionaryPlayers = [NSMutableDictionary dictionaryWithCapacity:10];
And do this right above your log statement (take it out of the init).
If this works, put a log in your init method and make sure that is being called before your method that adds KV's to the dictionary
I cannot reproduce this behavior. Here is my code:
ViewController.h:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property(nonatomic, retain) NSMutableDictionary *dictionaryPlayers;
#property (retain, nonatomic) IBOutlet UITextView *logTextView;
- (IBAction)logButtonPressed:(id)sender;
#end
ViewController.m:
#import "ViewController.h"
#implementation ViewController
#synthesize dictionaryPlayers;
#synthesize logTextView;
#pragma mark - My Methods
- (IBAction)logButtonPressed:(id)sender {
logTextView.text = [NSString stringWithFormat:#"%#,%d",[dictionaryPlayers description],[dictionaryPlayers count]];
NSLog(#"dictionaryPlayers=%#,%d",[dictionaryPlayers description],[dictionaryPlayers count]);
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
dictionaryPlayers = [[NSMutableDictionary alloc] init];
[dictionaryPlayers setValue:#"Test" forKey:#"testKey"];
NSLog(#"dictionaryPlayers=%#,%d",[dictionaryPlayers description],[dictionaryPlayers count]);
}
No issues. If you are doing things this way, you cannot have problems. Here are the steps I would take to troubleshoot further:
Do a project search for playersDictionary and make sure there isn't something else touching that object.
Try cleaning the project
Create a new project with this structure and see what happens

Cocoa Touch NSArray Initialization doesn't work properly

I have several ivar NSArrays that I initialize in my -viewDidLoad method. One contains strings, one contains IBOutlets. However, when I initialize, all of the objects in the array are out of scope, and the memory address is 0x0 (according to the Xcode debugger). However, when I have a local NSArray with the same objects, it works fine. Initializing an ivar NSString or NSDictionary both work fine.
The code:
//.h file
#import <UIKit/UIKit.h>
#interface myViewController : UIViewController
{
NSArray *myArray;
}
#end
//.m file
#import "myViewController.h"
#implementation myViewController
- (void)viewDidLoad
{
[super viewDidLoad];
myArray = [[NSArray alloc] initWithObjects:#"aString", #"another string", nil];
NSLog(#"myArray equals: %#.", myArray);
}
#end
When I try using the array, I get an EXC_BAD_ACCESS runtime error. Is this an Xcode bug, or am I missing something about NSArray? UPDATE: I am using ARC. After I turn ARC off and do a clean build, I no longer get this problem. Is this a bug in ARC?
I don't know what the problem was, but I switched to a stable version of Xcode (4.0.2) and I had NO problems at all. Thanks everyone for trying to help!
That you are using ARC is important to note when asking such a question.
How are you trying to use the array (show the code)? There is a known bug in certain versions of ARC (which can't be discussed on the iOS side, but the same bug is in the Lion release of ARC) where fast enumeration of a collection under ARC can cause a crash.
Sounds like the framework has not instantiated the IBOutlet instances yet. Can you hold off and populate the arrays in the viewWillAppear method? This will be called before the user sees anything. Otherwise pull them off of IB, just manage them manually and alloc them at whatever point you want.
Your sample code seems to be allocating a new (and local) version of myArray rather than setting the iVar you declare in your header file. Try changing:
NSArray *myArray = [[NSArray alloc] initWithObjects:#"aString", #"another string", nil];
to
myArray = [[NSArray alloc] initWithObjects:#"aString", #"another string", nil];
With ARC off, I would presume that any attempt you make to access myArray would do nothing because it would be set to nil and ignore all messages. I'm not sure why this code would work any differently with ARC enabled.

NSMutableDictionary not retaining values

I am semi-new to Objective-c and confused with why my NSMutableDictionary is not retaining information. I am declaring my variable in the header file:
#interface view_searchResults : UIViewController <UITableViewDataSource, UITableViewDelegate> {
NSMutableDictionary *imageDicationary;
}
#property (nonatomic, retain) NSMutableDictionary *imageDictionary;
Then in my .m file, I have the following:
#synthesize imageDictionary;
-(UIImage *)getImageForURL:(NSURL*)url {
UIImage*image;
image = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
[imageDictionary setObject:image forKey:#"test"];
if([imageDictionary objectForKey:#"test"]){
NSLog(#"Exists");
}
}
There is obviously other code to support this, but I can confirm that a URL is being passed, and the file is downloading correctly elsewhere. Also, I can confirm that this function is being executed, and I am not referring to the NSMutableDictionary anywhere else in the document.
Thanks!
Where do you create your NSMutable dictionary? If this really is all the code you have you need to create the dictionary:
#implementation view_searchResults
- (id) init;{
self = [super init];
if(self) {
imageDicationary = [NSMutableDictionary alloc] init]; // should also be released in dealloc.
}
return self;
}
If this is the error then the reason you are not causing a crash is because in objective-C it is valid to send a message to the nil object - it just does nothing.
You havent told us whether the "Exists" NSLog is executed, you also are NOT returning the image.
In other words, I fail to see your problem
Has imageDictionary been initialized? (alloc/init?)