3

I have just created an Extension for NSString class inside a Category class

#import "NSString+Name.h"

@interface NSString(Name)

@property (nonatomic, retain) NSString *var;

@end

But when i am trying to access that private variable inside the category class the app crashes and gives the error.

@implementation NSString (Name)

- (NSString*)newString{

    [self setVar:@"Its a new string"];    // Crashes here

    NSLog(@"name = %@",self.var);

    return self.var;
}

@end

Reason of crash

unrecognized selector sent to instance 0x1023641c8 2015-05-25 11:12:49.246 Tute[710:14433] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFConstantString setVar:]: unrecognized selector sent to instance 0x1023641c8'

If i am able to assign values in that variable then why its saying unrecognized selector

Tapas Pal
  • 7,073
  • 8
  • 39
  • 86
abhishekkharwar
  • 3,529
  • 2
  • 18
  • 31

3 Answers3

5

You should use Associated Objects. Find below the code this worked for me:

.h

@interface NSString (Name)

@property (nonatomic, assign)NSString *var;
- (NSString*)newString;
@end

.m

static char const * const Key = "SomeKey";

@implementation NSString (Name)

- (NSString*)newString
{
    self.var = @"Its a new string";
    NSLog(@"name = %@",self.var);

    return (self.var);
}

- (void)setVar:(NSString *)aVar {
    objc_setAssociatedObject(self, Key, aVar, OBJC_ASSOCIATION_ASSIGN);
}

- (NSString*)var {
    return (NSString*)objc_getAssociatedObject(self, Key);
}

Refer here, here and here

Vivek Molkar
  • 3,910
  • 1
  • 34
  • 46
  • This is the best way to add Variables in Apple create Classes [link](http://ddeville.me/2011/03/add-variables-to-an-existing-class-in-objective-c/) – Rajneesh May 25 '15 at 11:00
  • For future readers, the value of the key ("SomeKey") doesn't matter since you are just using the address of the key, therefor I just use `static void * const kAssociatedStorageKey = (void*)&kAssociatedStorageKey;` – Albert Renshaw Mar 12 '19 at 04:46
2

There are a few issues with what you're trying to do.

  1. You can't conventionally add properties to a category.

From Apple's [Programming with Objective C][1] documentation:

Categories can be used to declare either instance methods or class methods but are not usually suitable for declaring additional properties.

A category can add something called an associated object, but its primary purpose is to add methods.

  1. Self within a category instance method refers to an instance variable

A category instance method (one that begins with a -) operates on the instance variable that calls the method. Within the instance method, self refers to the caller instance variable, not a class (or a category property, as you attempted to access).

In your category example, you'd be calling newString from an existing NSString, like so:

NSString *myString = @"foo";
[myString newString];

In other words, the newString category extension operates on the string that called it. You can change that string, or return a different result, but the issue is that you're operating on an NSString which has no such var property or method.

That's why you're seeing a 'No such selector message,' as NSString knows nothing about an unrelated property you happened to add to your category.

  1. Methods beginning with new have specific meaning for ARC.

The other issue, is that you've began the method with 'new'. There are some specific naming conventions for Objective-C that have to do with memory management policy. Starting a method with alloc, new, copy, or mutableCopy implicitly tells ARC that your method (has created and) is returning a retained object. Your newString method did not create an object.

Panda
  • 6,955
  • 6
  • 40
  • 55
1

use _ instead of self it will goes to infinite loop

- (NSString*)newString
{

    _var = @"Its a new string";
    NSLog(@"name = %@",_var);

    return (self.var);
}
Esha
  • 1,328
  • 13
  • 34
Ghanshyam Tomar
  • 762
  • 1
  • 8
  • 24