0

I am testing a simple UIPickerView app so that I can use it as a class in my project... the code works beautifully with ARC but as soon as I turn ARC off the build succeeds but crashes when I click on the display of the picker...the error displayed is "EXC_BAD_ACCESS(code=2, address=oxc)" at the line

    return [pickerData1 objectAtIndex:row];

will be extremely grateful if someone can help...I have spent more than 7 working days [60hours+] trying all sorts of options given on the stackoverflow website but just can't get around the issue...needless to say I am trying to learn...

...i have learnt this much that there is a problem with the array...it is being released whereas it should be retained till the 'objectAtIndex' call...but I have tried countless ways of going about this none worked...its because i don't have an in-depth understanding of xcode as yet...trying to learn by doing...usually i am successful in figuring out how to apply sample code in my project and have successfully completed many complex parts of my project (it is an iPad app that deploys augmented reality technology), but am desperately stuck at this rather simple component...

this is the header file:

#import <UIKit/UIKit.h>

@interface PickerText : UIViewController<UIPickerViewDataSource, UIPickerViewDelegate>
{
    NSArray *pickerData1;
}
@property (retain, nonatomic) IBOutlet UIPickerView *picker1;
@property (retain, nonatomic) IBOutlet UIButton *buttonForSelection1;
@end

and this is the implementation file

#import "PickerText.h"

@interface PickerText ()

//set tags to enable future incorporation of multiple pickers
#define kPICKER1COLUMN 1
#define kPICKER1TAG 21
#define kButton1Tag 31

@end

@implementation PickerText

@synthesize picker1;
@synthesize buttonForSelection1;

- (void)viewDidLoad
{
    [super viewDidLoad];

// assign data in array
   pickerData1 = @[@"[tap to select]", @"Item 1", @"Item 2", @"Item 3", @"Item 4", @"Item 5", @"Item 6"];

// Connect data
picker1.tag = kPICKER1TAG;
self.picker1.dataSource = self;
self.picker1.delegate = self;
picker1.hidden = YES;   
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

// set number of columns of data in picker view
- (int)numberOfComponentsInPickerView:(UIPickerView *)pickerView

{
    if (pickerView.tag == kPICKER1TAG)
        return kPICKER1COLUMN;
    else { return 0; }
}

// The number of rows of data
- (int)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component

{
    if (pickerView.tag == kPICKER1TAG)
        return [pickerData1 count];
    else { return 0; }
}

// The data to return for the row and component (column) that's being passed in (ie set the data in picker view)...

//method using NSString
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{   
    if (pickerView.tag == kPICKER1TAG)
        return [pickerData1 objectAtIndex:row];
    else { return 0; }  
}

// Capture the picker view selection
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
    if (pickerView.tag == kPICKER1TAG)
    {
        NSString *selection1  = [pickerData1 objectAtIndex:[picker1 selectedRowInComponent:0]];

    //check selection
    NSLog(@"%@", selection1);

    //change display text on button
    [buttonForSelection1 setTitle:selection1 forState:UIControlStateNormal];
    [buttonForSelection1 setTitle:selection1 forState:UIControlStateSelected];
    }

    //to hide picker view after selection
    pickerView.hidden=YES;      
}


- (IBAction)showPicker:(id)sender
{
    if ([sender tag] == kButton1Tag)
    {
        picker1.hidden = NO;
    }
}

@end

many thanks in advance!!

Code cracker
  • 3,105
  • 6
  • 37
  • 67
mak
  • 3
  • 5
  • Why would you turn ARC off? Did you look at options to enable/disable ARC on a [file-by-file basis](http://stackoverflow.com/a/11255187/938783)? – Allen Zeng Sep 17 '14 at 01:39
  • whoa!!! didn't know about that...will look it up and will be back in a few minutes...!! – mak Sep 17 '14 at 01:41
  • YESSS !!!! hi-five!! thanks so much @AllenZeng !!! ....i found the info at: http://stackoverflow.com/questions/6448874/disable-automatic-reference-counting-for-some-files ..... and inserted the files as a class in my project...bingo! working so far...in case i have any issues then will get back....God Bless you!!! – mak Sep 17 '14 at 02:06
  • 1
    If you aren't going to use ARC then you need to retain your array `pickerData1 = [@[@"[tap to select]", @"Item 1", @"Item 2", @"Item 3", @"Item 4", @"Item 5", @"Item 6"] retain]; – Paulw11 Sep 17 '14 at 02:10
  • Thanks @Paulw11, will try that if needed...so far the above option is working...many thanks !!! – mak Sep 17 '14 at 02:11
  • in my opinion, before learning this tricks of turning ARC on and off, you should first learn the basics of retain and assign and the also go through the ARC release notes. It will help you much more in the future. – devluv Sep 17 '14 at 02:14
  • PLEASE NOTE: when i used the option to turn ARC on for the file there was a memory leak indication....so I have finally implemented the idea given by @Paulw11....!!! – mak Sep 17 '14 at 06:31

2 Answers2

1

And in case if you want to know what the issue is with ARC turned off. The Problem is here:(1)

@interface PickerText : UIViewController<UIPickerViewDataSource, UIPickerViewDelegate>
{
    NSArray *pickerData1;
}

and here(2) -

pickerData1 = @[@"[tap to select]", @"Item 1", @"Item 2", @"Item 3", @"Item 4", @"Item 5", @"Item 6"];

You see, in ARC the default association is strong so when you write the second line, THE pickerData1 holds a strong reference to the autorelease array and it all works properly. But without ARC the default association is assign hence , since in line 2 you have assigned an autorelease array (which is getting released at some later point of time), you are getting the crash. You can learn the difference between assign and strong in the Apple documents.

Better you change the array to a strong property. Though without ARC, strong will simply mean retain.

Cheers, have fun.

devluv
  • 2,007
  • 13
  • 13
  • Thanks to you too @croyneaus4u !!! nice lesson for me ....after 8 days of sweat!!! whew!!!...will refer back as/when needed...many thanks – mak Sep 17 '14 at 02:14
  • This should probably be the answer because it's more in accordance with the question - which is getting it to work without ARC – Allen Zeng Sep 17 '14 at 02:15
  • ok with me...i'll change the check...thanks again to all, this is a wonderful first experience on stack overflow...hope to be in touch...God Bless you all.. – mak Sep 17 '14 at 04:26
  • PLEASE NOTE: when i used the option to turn ARC on for the file there was a memory leak indication....so I have finally implemented the idea given by @Paulw11....!!! – – mak Sep 17 '14 at 06:32
0

Don't bother turning ARC off. You have the option to enable/disable ARC on a file-by-file basis:

  • -fobjc-arc to turn ARC on for a file in a project that doesn't work with ARC
  • -fno-objc-arc vice-versa
Community
  • 1
  • 1
Allen Zeng
  • 2,635
  • 2
  • 20
  • 31
  • yes!!! and the way to do that is given here: http://stackoverflow.com/questions/6448874/disable-automatic-reference-counting-for-some-files... – mak Sep 17 '14 at 04:35
  • PLEASE NOTE: when i used the option to turn ARC on for the file there was a memory leak indication....so I have finally implemented the idea given by @Paulw11....!!! – – mak Sep 17 '14 at 06:33
  • It's most likely a leak from your code. Take a closer look at Instruments. – Allen Zeng Sep 17 '14 at 06:35