views:

406

answers:

2

I want store a URL against a UILabel so that when a user touches the label it takes them to that URL in a UIWebView.

I have declared a NSDictionary like so:

NSMutableArray *linksArray = [[NSMutableArray alloc] init];
[linksArray addObject: [NSValue valueWithNonretainedObject: newsItem1ReadMoreLabel]];
[linksArray addObject: [NSValue valueWithNonretainedObject: newsItem2ReadMoreLabel]];
[linksArray addObject: [NSValue valueWithNonretainedObject: newsItem3ReadMoreLabel]];
[linksArray addObject: [NSValue valueWithNonretainedObject: newsItem4ReadMoreLabel]];
[linksArray addObject: [NSValue valueWithNonretainedObject: newsItem5ReadMoreLabel]];
//NSString *ageLink = @"http://www.theage.com.au";
NSArray *defaultLinks = [NSArray arrayWithObjects: @"1", @"2", @"3", @"4", @"5", nil];
self.urlToLinkDictionary = [[NSMutableDictionary alloc] init];
self.urlToLinkDictionary = [NSDictionary dictionaryWithObjects:defaultLinks forKeys:linksArray];

Considering I used a NSValue as the key, how do I get/set the URL associated with that key given that I only have references to the UILabels?

this is what I have but it doesn't work:

for(NSValue *key in [self.urlToLinkDictionary allKeys])
{
    if ([key nonretainedObjectValue] == linkedLabel)
    {
        [self.urlToLinkDictionary setValue:[newsItem link] forKey: key];
    }
}

but I get an error: "objc_exception_throw" resolved

A: 

Why not try a more simplified approach. Associate a tag with every label. The tag is a in integer value and you can use it to locate the url in an array.

So code for creating the array.

NSMutableArray* arrayURLs = [NSMutableArray arrayWithCapacity:2];
newsItem1ReadMoreLabel.tag = 0;
[arrayURLs insertObject:urlStringforLabel1 atIndex:newsItem1ReadMoreLabel.tag];
newsItem2ReadMoreLabel.tag = 1;
[arrayURLs insertObject:urlStringforLabel2 atIndex:newsItem2ReadMoreLabel.tag];

then you can access the urlstring for the appropriate label

NSString* url = [arrayURLs objectAtIndex:labelClicked.tag];
Bharat Ahluwalia
A: 

These two lines are the cause of the issue:

self.urlToLinkDictionary = [[NSMutableDictionary alloc] init];
self.urlToLinkDictionary = [NSDictionary dictionaryWithObjects:defaultLinks forKeys:linksArray];

First you assign a mutable array to the property. Then you assign a different immutable array to the property. Your original mutable array leaks because you don't release it.

The exception is being caused by this line:

[self.urlToLinkDictionary setValue:[newsItem link] forKey: key];

By the time you get to it, self.urlToLinkDictionary is an immutable dictionary. You can't change it.

There are other problems:

  • linksArray leaks because you never release it.
  • newsItem1ReadMoreLabel etc. What type are they? Why are you wrapping them in values?
  • setValue:forKey: is part of key value coding. On a mutable dictionary it works, but the correct method for accessing objects by keys is setObject:forKey:
  • it seems a bit pointless to search a dictionary by doing a linear search through its keys.
JeremyP