Question

So, I understand that Categories in Objective-C can be used to add methods to classes without the need for subclassing. I also understand that these Categories cannot be used to add instance variables to classes.

I did a little bit of reading about Class Extensions, which can be used to add instance variables, but I don't understand how I can use Class Extensions to modify an existing class such as NSData.

My problem is the following:

I have a Core Data Model that contains a NSURL and NSData. The NSData displays the data for the NSURL. When a view needs to display the data, I do the following check: --- If [NSData bytes] > 0, display the NSData. --- Otherwise, fetch the data at NSURL and display the data when it returns

Simple enough. However, I run into problems when the NSURL is updated. So, if I modify the NSURL path with a new image, because [NSData bytes] is already greater than 0, I don't make the additional call to fetch the new image.

What I would like to do is add an instance variable to NSData called URLKey that would hold information about where the data comes from. I can't subclass NSData because I'm using CoreData.

Does anyone know some simple solutions for this? Perhaps there's a gap in my understanding of Class Extensions, or maybe there's just no simple way.

Was it helpful?

Solution

Class Extensions should be used on classes you implement yourself as a way of keeping ivars and some properties hidden from the header File, that should contain only stuff that should be visible outside the class (and ivars are't that kind of stuff).

Categories are used on classes already implemented, as a way of adding additional functionality. They are usually needed when you want to add a general kind of behavior to a known Class. E.g. adding a method to NSString +(NSString*)reversedString; that returns a reversed instance so you can then use it like this:

NSString *someString = @"string";
NSString *reverse = [someString reversedString]; 
NSLog(@"%@", someString); //this would output "gnirts"

.

Regarding your particular problem, I can assure you that your CoreDataModel does not contain NSURL or NSData. The supported types are primitives, strings, binary Data and transformables. So, if you want to, you can subclass NSData or NSURL and then use it with CoreData by setting the type to "transformable". And after you have done this, you can then subclass NSData as you wish and use class extensions in the process, or just use a category to add the methods you require to the class.

Quote from Apple about transformable attributes:

The idea behind transformable attributes is that you access an attribute as a non-standard type, but behind the scenes Core Data uses an instance of NSValueTransformer to convert the attribute to and from an instance of NSData. Core Data then stores the data instance to the persistent store.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top