I'm a kind of self-programmer-made-man, so I'm missing some basic knowledge from time to time.
That's why I'm unable to really define well the topic of my question, because I don't know how to name it and how it works (but I know answer will seem trivial to many of you). When you know what's you're looking for it's a lot easier to find answers.
In objective-c, I can see lines of code like this :
aClassName *myObject = (aClassName *)[NSEntityDescription insertNewObjectForEntityForName:#"aClassName" inManagedObjectContext:app.managedObjectContext];
What's bother me is that (aClass *) part. What's this ?
I know/feel it's related to very basic knowledge but I can't name it so I can't find it.
My guess (and that's how I use it up to now) is that's used for calling class methods (+) but i'm not sure of it and it may be more deep that what I understand.
Thanks for any explanation.
It's a cast, in this case a down cast (even because up casts are implicit).
A cast is an operation that the developer does while writing the code to hint the compiler that a type is narrower than the one the compiler is thinking about.
Think about the following situation:
Class *a = [[Subclass alloc] init];
Subclass *b = a;
(assume that Subclass is a subclass of Class)
This won't compile because a is statically defined with a type which is not contained in Subclass. But the assignment wouldn't create any problem dynamically because a is used to store a Subclass object in practice.
So what you do? You place a cast Subclass *b = (Subclass*)a; to tell the compiler "trust me and ignore typechecking that assignment, I assert that it will be valid a runtime", and you automagically remove the compilation error. Forcing this behaviour of course removes type safety from your code, so you must know what you are doing.
Of course to understand the meaning of a cast in this situation you must at least know about inheritance and objects..
In your specific situation the return type of the method +(id)insertNewObjectForEntityForName:... is id, which is the least specific kind of object in ObjectiveC, it always needs to be casted to something if not stored just like a plain id
It is type cast:
double x = 5.0;
int y = (int)x;
I don't know why it is there in your case, as far as I know that method returns id, so the cast is not necessary (even without it no compiler warning will be generated).
Regarding “where to find such information”: Objective-C/C++ are built upon C and C++ correspondingly, so I'd recommend to learn basics of those languages first.
thats simply mean casting the object to type of the class inside the brackets for example here we cast the defention UITableViewCell to CustomCell
CustomeCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = (CustomeCell*)[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
... class methode is a different somthing its function that you can call without need to define an instance of the class ... when you call a instance method you need to do like this
Class *obj = [Class alloc] init];
[obj funtionName];
in Class ethod you just do like this
[Class funtionName];
hope this will be helpful.
Related
In the following code
id<SwiftProtocol> anotherInstanceAsProtocol = [[SomeObjectiveCClassImplementingOBJCSwiftProtocol alloc] init];
[anotherInstanceAsProtocol isKindOfClass:[SomeObjectiveCClassImplementingOBJCSwiftProtocol class]];
I get the warning "No known instance method for selector 'isKindOfClass:'"
If I modify the last line to
[(id)anotherInstanceAsProtocol isKindOfClass:[SomeObjectiveCClassImplementingOBJCSwiftProtocol class]]
It runs perfectly.
It also works if I assign to NSObject<SwiftProtocol> instead of id<SwiftProtocol>, but I think neither should be necessary.
Why is this cast necessary?
The problem is that your SwiftProtocol does not inherit from NSObject(Protocol) therefore the Obj-C compiler does not know that there is a method called isKindOfClass:.
Using id basically means you don't want any type checking at compilation time. The real fix should be to make the protocol extend NSObjectProtocol, making sure that all instances conforming to it are normal Obj-C objects.
Note that the history of Objective-C is complicated and not all Objective-C objects have to inherit from NSObject and have isKindOfClass: available.
Well, in obj-c have the ability of change the class of a declared var. So if I declare myVar as a NSString, is possible to get back later a NSNUmber.
I have this problem now, but I can't find where in my code is the identity swap... exist a way to find it? For example is possible to set a breakpoint where [myVar class] == [NSString class] and when change know it?
You may be confused about the static type of a pointer, and the actual type of the object it points to. Consider this code:
NSString *test = #"test";
NSNumber *notReallyANumber = (NSNumber *)test;
This is valid code, but it didn't "transform" test into an NSNumber. It's still a string, just with an incorrect type on the pointer.
Basically, no, you don't have the ability to change the class of a variable (you do, but it's deep deep magic and almost never occurs).
Would someone please clarify what the difference in these two snippets would be?
I know this is instantiation:
Class *myClass = [[Class alloc] init] ....etc
but what exactly is this?
(Class *)myClass .....etc
Thanks
The second snippet is either a cast or a parameter to a method. Neither have anything to do with instantiation.
If (Class *)myClass occurs in a method declaration, it just defines what type the parameter to the method should be. For example, - (void) method:(Class *)myClass is a method that returns void and takes one argument, of type Class*.
If (Class *)myClass occurs in other code, it's a cast. Basically it says to reinterpret myClass as a pointer to an object of type Class, regardless of what its type really is. It's like casting with numbers - if x is an int, (float)x casts it as a float so you can use it in floating-point arithmetic.
Generally speaking, I'd caution you against using casting heavily with Objective-C objects. One place you will see things like this is in casting NS objects to CF objects, as in (CFURLRef)[NSURL fileURLWithPath:path]. But most often objects of different types will not cast properly.
Also, you have an error in your first snippet. It would actually be [[Class alloc] init]. You must call alloc and then init. And [init] is meaningless - it doesn't fit the [object method] syntax of Objective-C at all.
The first one, given correct syntax is instantiating, as you say.
The second one is casting a variable "myClass" to a pointer to an instance of the Class object.
The second snippet is a C-style cast. It effectively tells the compiler to treat myClass as a value of type Class* regardless of its declared type. Without the rest of the snippet (and the preceeding declaration of myClass), it's impossible to say why you would want to use the cast or what effect it would have.
I have next situation:
Method:
-(void) myMethod:(id)inValue
{
long a = [inValue longValue];
}
Compiler shows me a warning that -longValue - is multiplied:
multiple methods named '-longValue' found
What can I do to resolve this warning without change method name?
Thank!
Strongly type your method's argument to tell the compiler which variant of the -longValue message you want to use, e.g.:
-(void) myMethod:(NSNumber *)inValue
{
long a = [inValue longValue];
}
If you want to accept multiple types that respond to -longValue (say, NSNumber and NSString) then you'll have to go back to using id and you'll see the warning. You see, something in your (yes, your, not Apple's) class hierarchy has bunged up and used a different signature for -longValue, so the compiler has no way of knowing which one you want to use. id tells it "this is an object" but it provides no explicit information that the compiler can use to resolve its conundrum.
Is there a particular reason why you're passing an id instead of a strongly-typed object?
I'm understood where from this warning - it completely right. If I were compiler developer - I were make possible something like this:
id a = [[[inValue class] alloc]] init];
for type cast; and after this may be:
a = inValue
[a longValue];
for resolve this warning.
But I'm not.)
And I'm only study programming for Mac. So i just asking - it possible or not.
Just like back in the pre-generics Java days, I write code like this:
UIView *ball = [self.balls objectAtIndex:i];
which causes a compiler warning. I know that correct way to resolve it -- assuming it doesn't blow up at runtime -- is to use
UIView *ball = (UIView *)[self.balls objectAtIndex:i];
but recently I've been favoring
UIView *ball = (id)[self.balls objectAtIndex:i];
Is there ANY reason not to do this? Does it change anything at runtime? It's easier to type and read, I think.
Either you've defined a custom type that responds to objectAtIndex: rather than using a built-in array or there is something wrong with your setup. NSArray's objectAtIndex: is defined to return type 'id', so casting the result to type 'id' has no effect. Furthermore, objects of any type can be assigned to id and objects of type id can be assigned to any other type without generating a compiler warning.
In any event, pointer casting has no effect at runtime. Objective-C does not modify the way that pointers work in C other than supplying a few additional implicit conversions.