Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSURL - No mutable subclass, so no need to "copy" as a property?

@interface SomeClass : NSObject

@property (copy,   nonatomic) NSString *usefulString;
@property (strong, nonatomic) NSString *dangerousString;

@property (copy,   nonatomic) NSURL *curiousURLOne;
@property (strong, nonatomic) NSURL *curiousURLTwo;

@end

In the above class, dangerousString is considered a bad idea because NSMutableString inherits from NSString. Meaning it is possible a user of your class could set a mutable string to dangerousString, and then later change the value of the mutable string out from underneath the instance of SomeClass. The property usefulString doesn't have this danger as it copies the value into a new (immutable) string object.

However, it seems like for NSURL (and any other foundation classes that don't have mutable counterparts - e.g. NSNumber) the copy semantic of the property declaration is unnecessary. NSURL does conform to NSCopying's copyWithZone: (...but I have to wonder if it doesn't just return the same object with an increased retain count - why would it do anything else?)

Why would you declare properties as copy that don't have a danger of being mutated?

like image 437
edelaney05 Avatar asked Dec 21 '12 02:12

edelaney05


Video Answer


2 Answers

With iOS7 you can use NSURLComponents, now it's very simple, look this examples:

NSString *urlString = @"https://mail.google.com/mail/u/0/?shva=1#inbox";
NSURLComponents *components = [[NSURLComponents alloc] initWithString:urlString];

NSLog(@"%@ - %@ - %@ - %@", components.scheme, components.host, components.query, components.fragment);



NSURLComponents *components = [NSURLComponents new];
[components setScheme:@"https"];
[components setHost:@"mail.google.com"];
[components setQuery:@"shva=1"];
[components setFragment:@"inbox"];
[components setPath:@"/mail/u/0/"];

[webview loadRequest:[[NSURLRequest alloc] initWithURL:[components URL]]];
like image 127
Salmo Avatar answered Oct 29 '22 03:10

Salmo


The fact that Apple does not supply a mutable subclass does not mean that a malicious user could not build one specifically to trick your class. If you operate under the assumption that strings can be changed behind your class's back, you need to at least allow for a possibility of an ill-intentioned user extending NSURL into a mutable class:

@interface TrickThemURL : NSURL
    // override key properties, such as baseURL and host, to be mutable
@end

If a programmer gives you an object of TrickThemURL and you fail to copy it before the validation, that programmer is now free to change the URL without letting your class know.

like image 42
Sergey Kalinichenko Avatar answered Oct 29 '22 04:10

Sergey Kalinichenko