what is the difference between (NSString) *name and (NSString *) name in objective c - objective-c

i can't understand when to use (NSString *) name and when to use (NSString) *name.
i hope someone can help me/

You should never need to use (NSString)*name. NSString * is a type: a pointer to an instance of NSString. So in a method declaration like this:
- (NSString *)capitalisedString: (NSString *)string
Each time (NSString *) appears it means "the thing that follows has type NSString *". The first one means that the return value of the method is an NSString instance, the second means that the type of the argument string is an NSString instance.
This discussion also applies to casting, which is when you tell a compiler to treat a variable as if it's of a particular type. Because NSString * is a type, you would cast like this:
id object = //...
NSString *myString = (NSString *)object;

The parentheses constitute a cast operator. I.e. (NSString*) name means, that the compiler should interpret name as a pointer to NSString; whereas (NSString) *name means that the compiler should interpret the dereferenced value (i.e., the value name points to) as NSString.

Related

Objective C - Category No Visible selector #removeWhiteSpaceStringWithString

so im trying to add new method for testing using Category from NSString, but some how i must declared like this with following step:
Create Category from NSString with name StringExtension so it will be NSString+StringExtension, after that i declared my own methos that return type is String
so after i define in NSString+StringExtension #interface and #implementation, i tried in my viewController to called it, but first i import the class NSString+StringExtension
after that i do like this
NSString *testString = #"as d a s d";
NSLog(#"===== %#", [testString removeWhiteSpaceStringWithString:testString]);
and it says
No visible #interface for 'NSString' declares the selector 'removeWhiteSpaceStringWithString:'
the question is, why it cannot use like that? i already search and see tutorial doing like that and its possible, but why i'm not able to do that?
so i found this way, but i don't know is this the correct code to use?
NSLog(#"===== %#", [[testString class] removeWhiteSpaceStringWithString:testString]);
anyone have the same case like i am?
Based upon what you have shared with us, it would appear that you defined a class method (with +). It should be an instance method (with -) and then you don’t need the parameter, either. You can simply reference self.
For example:
// NSString+Whitespace.h
#import Foundation;
NS_ASSUME_NONNULL_BEGIN
#interface NSString (Whitespace)
- (NSString *)stringByRemovingWhitespace;
#end
NS_ASSUME_NONNULL_END
And
// NSString+Whitespace.m
#import "NSString+Whitespace.h"
#implementation NSString (Whitespace)
- (NSString *)stringByRemovingWhitespace {
return [self stringByReplacingOccurrencesOfString:#"\\s+"
withString:#""
options:NSRegularExpressionSearch
range:NSMakeRange(0, self.length)];
}
#end
Then you can do:
NSString *testString = #"as d a s d";
NSLog(#"===== %#", [testString stringByRemovingWhitespace]); // ===== asdasd
Obviously, do whatever you want in your implementation, but it illustrates the idea, that you want an instance method and you do not need to pass the string again as a parameter.

Objective-C method parameter with ^ symbol

One of the method signature in objective-c code
-(void)funcName: (const NSString *)name parameter: (void(^)(ClassName *input)) obj
The class definition header file is
#interface ClassName : NSObject
#property NSObject *data;
#end
Now how to prepare and pass the second paramater?
you can pass a block as a parameter for instance like:
option 1.
[... funcName:#"" parameter:^(ClassName * input) {
NSLog(#"I'm inside the block!");
}];
option 2.
void(^myBlock)(ClassName *) = ^(ClassName * input) {
NSLog(#"I'm inside the block!");
};
[... funcName:#"" parameter:myBlock];
both options can work, you can use whichever makes more sense to you.
When writing your own methods in Objective-C parameters must be explicitly type casted to the data type that you would like to pass through. The ^ symbol signifys that you are passing in a block. If you would like to pass another parameter after the block - you would simply add the next part of the method name followed by the data type, and then your choice of the variable name. You would do so like this:
-(void)funcName: (const NSString *)name parameter: (void(^)(ClassName *input)) obj withOtherParameter:(NSString *) param {
// Use it here and do what you will
NSLog(#"Param = %#", param);
}
This assumes you are passing in an NSString to be called "param". If you would like to pass in any other data type, just replace the (NSString *) with (NSNumber *) or (NSInteger) before the "param" in the code and then the param variable will be cast as whatever data type you would like.

"sending 'const NSString *' to parameter of type 'NSString *' discards qualifiers" warning

I have Constants NSString, that I want to call like:
[newString isEqualToString:CONSTANT_STRING];
Any wrong code here?
I got this warning:
sending 'const NSString *' to parameter of type 'NSString *' discards qualifiers
How should these be declared?
You should declare your constant string as follows:
NSString * const kSomeConstantString = #""; // constant pointer
instead of:
const NSString * kSomeConstantString = #""; // pointer to constant
// equivalent to
NSString const * kSomeConstantString = #"";
The former is a constant pointer to an NSString object, while the latter is a pointer to a constant NSString object.
Using a NSString * const prevents you from reassigning kSomeConstantString to point to a different NSString object.
The method isEqualToString: expects an argument of type NSString *. If you pass a pointer to a constant string (const NSString *), you are passing something different than it expects.
Besides, NSString objects are already immutable, so making them const NSString is meaningless.
just to put all on one place which found on various post on stackoverflow and works for me , #define is bad because you cannot benefit from variable types, basically the compiler replaces all occurrence when compiles (import Constants.h whenever you need) :
// Constants.h
#import <Foundation/Foundation.h>
#interface Constants : NSObject
extern NSString *APP_STATE_LOGGED_IN;
extern NSString *APP_STATE_LOGGED_OUT;
#end
// Constants.m
#import <Foundation/Foundation.h>
#import "Constants.h"
#implementation Constants
NSString *APP_STATE_LOGGED_IN = #"APP_STATE_LOGGED_IN";
NSString *APP_STATE_LOGGED_OUT = #"APP_STATE_LOGGED_OUT";
#end
spare few minutes to read this. A goodread on pointers hell on constants and vice-versa.
http://c-faq.com/decl/spiral.anderson.html

NSString inheritance

I'm doing an useless thing for my first step in Obj-C
#interface String : NSString
{
int m_isnull;
}
- (id) init;
- (int) isNull;
#end
#implementation String
- (id) init
{
self = [super init];
m_isnull=1;
return self;
}
- (int) isNull
{
return m_isnull;
}
#end
test :
String *a;
a=#"ok";
Works fine, but just 2 little questions
1) When I'm compiling I have this warning
warning: incompatible Objective-C types assigning 'struct NSString *', expected 'struct String *'
I don't know how to avoid it !?
2) a=#"ok" is a fastest way to initialize a string, but when I'm debugging, I don't stop by at my init constructor why ?
#"ok" is actually a NSString like 1 is an integer. That's why you get this compiler warning.
There are also #"" NSString literals.
It is essentially shorthand for
NSString's +stringWithUTF8String
method. Mac Player
already stated that it is used to
distinguish this sort of string
literal from a char * string literal
in C.
Source http://guides.macrumors.com/Objective-C_Tutorial#The_.40_symbol
Normally you would create a Category in Objective-C to extend the NSString Class.
Take a look at the NSString class reference:
It is possible to subclass NSString (and NSMutableString), but doing so requires providing storage facilities for the string (which is not inherited by subclasses) and implementing two primitive methods. The abstract NSString and NSMutableString classes are the public interface of a class cluster consisting mostly of private, concrete classes that create and return a string object appropriate for a given situation. Making your own concrete subclass of this cluster imposes certain requirements (discussed in “Methods to Override”).
If you really want to add an -isNull method to NSString you would probably be better off adding it as a category.
I think you might also want to try writing -(BOOL) isNotBlank instead. Consider what happens if you call -isNull on a nil pointer, is that the return value you would expect?
#"ok" is an NSString object. You're creating an instance of the superclass and trying to assign it to a subclass pointer. Think of subclassing as an "is-a" relationship. In your example, String is an NSString. NSString is not a String. Therefore, you can't assign an NSString object to a String pointer.

Can someone explain to me what (NSString *) means with Obj-C?

I just started with Objective-C and I would like to understand the meaning of the following lines of code as I see it everywhere in objective-c but I'm not quite getting it 100%:
- (id)initWithName:(NSString *)name;
I understand that the above line is a instance method passing one argument, what I don't understand is (NSString *)name.
another example is:
-(NSString *)name;
or
person.height = (NSObject *)something;
Thanks for your help
In this line:
- (id)initWithName:(NSString *)name;
(NSString *) is simply the type of the argument - a string object, which is the NSString class in Cocoa. In Objective-C you're always dealing with object references (pointers), so the "*" indicates that the argument is a reference to an NSString object.
In this example:
person.height = (NSObject *)something;
something a little different is happening: (NSObject *) is again specifying a type, but this time it's a "type casting" operation -- what this means is to take the "something" object reference (which could be an NSString, NSNumber, or ...) and treat it as a reference to an NSObject.
update -
When talking about Objective-C objects (as opposed to primitive types like int or float), everything's ultimately a pointer, so the cast operation means "take this pointer an X and treat it as if it's pointing to a Y". For example, if you have a container class (like NSArray) that holds generic NSObjects, but you know that the the objects are actually strings, you might say:
NSString *myString = (NSString *)[myArray objectAtIndex:0];
which means "retrieve the first object from the array, treating it as a string".
The cast is not actually converting the value, it's just a way of saying to the compiler "hey, I know that I'm assigning an X to a Y here, so don't give me a warning about it".
- (id)initWithName:(NSString*)name;
Is a signature of a method that takes one parameter called name which is a pointer to NSString.
-(NSString *)name;
Is an accessor method called name that returns pointer to NSString.
person.height = (NSObject *)something;
Typecasts something to a NSObject pointer and then it is assigned to person.height property.
See more explanation in Learning Objective-C: A Primer
- (id)initWithName:(NSString *)name;
-----------------------------------------
'-' means its an instance method (+ is used for static methods)
'(id)' is the return type
'initWithName' is the function name, the name implies its a constructor
':' start of parameter
'(NSString*)' parameter type
'name' parameter name
its the equivalent of
(id)initWithName( NSString* name )
(NSString *)name
is saying that a variable name is a pointer * to a NSString object. Its a pointer because the name variable isn't the string but rather it is just the address in memory for that string.