NSMutableArray and indexAtObject - ios

I am a newbie to Objective-C and I am working on getting a good handle in working with arrays.
According to Apples own documentation NSMutableArray inherits from NSArray. I am seeking to use the method objectAtIndex:i within a for loop. Yet Xcode is claiming that
"Property 'objectAtIndex' not found on object of type
'NSMutableArray'".
Within a for loop I am performing (or seeking to) the following test:
if([self.cards objectAtIndex:i].isChosen){
do something here }
I am certain I not doing this right. It can be frustrating learning the idiosyncrasies of a new programming language. For me Objective C has, so far, borne little resemblance to C++ or C.
Any pointer or assistance would be greatly appreciated.
Thanks in advance
Walt Williams

From your error message, you could not be using the method and parameter correctly. Possibly you're trying to use a dot notation?
Your code should be like:
id object = [array objectAtIndex:index];
where the index comes from your loop and you then use the object.

In addition to Wain's answer, which is correct, but for the sake of completeness, you are using the array and trying to call the method this way:
Ex:
array.objectAtIndex.i = 5; //Java.....?
which is the cause of this error:
"Property 'objectAtIndex' not found on object of type
'NSMutableArray'".
It is complaining that you are trying to access a property named "objectAtIndex", which of course, doesn't exist.
You mean to call the method:
[array objectAtIndex:i];
In Objective-C, it is called "you are sending a message (objectAtIndex:i) to the array".

I am guessing, but hard to tell without your header file declarations, that your problem is you need to #import the file where your class is declared. This is the most common problem when having issues like this. It somehow does not know that it is an NSMutableArray. Also as I noted above you need to assign the value you get back from the array into a typed variable of that class so that you can then access the isChosen property.

Related

How to call a method from an object in an array?

I'm new to Objective-c and I think this should be really easy but somehow I can't figure it out.
I need to call a method from an object which is stored in an NSArray.
The Java code would be: myArray[0].getMyValue();
So I read on the internet that in Objective-c it should look like this: [[myArray objectAtIndex: 0] getMyValue]. Unfortunately this didn't work.
I found other solutions on the internet but none of them worked.
So I hope you guys could help me out?
Update
I'm getting these two error messages:
No known instance method for selector 'getMyValue'
Sending 'id' to parameter of incompatible type 'CGFloat' (aka 'double')
This doesn't work because Objective-C doesn't know what is the type of the object in the array.
Luckily, Apple has added lightweight generics in Xcode 7, which allow you to create typed arrays. This will of course work only if you intend to have one type of object in the array. The syntax looks like this:
NSArray<NSString *> *stringArray;
If you plan to have objects with different types in the array, then you need to cast the object to your type, to be able to call your method. That would look like this:
[((YourObject *)[myArray objectAtIndex: 0]) getMyValue];
And as #Michael pointed out in the comment, another and nicer way to do this would be:
[((YourObject *)myArray[0]) getMyValue];
Objects are stored with id type in NSArray, so you can cast this object to the object type you want. For instance :
NSNumber *myNumber = (NSNumber *)[NSArray objectAtIndex:0];
[myNumber myMethod];

Typedef NSArray of type in Objective C

It has been a long time since I have worked in Objective C but now I am using it because I need to write something that will remain mostly source compatible for future versions. I want to create an init method that allows me to init my viewController with an array of my custom model object. In Swift I would do it like this:
typealias Stack = [StackBarTabItem]
…
func init(stacks:[Stack])
But how would I typedef an NSArray like that? I am pretty sure I can't do something like typedef NSArray<StackBarTabItem> Stack; so what is the syntax in objective c?
Until iOS 9 and Xcode 7, this isn't officially supported. One way to do this is to subclass NSArray or NSMutableArray and enforce typing in your subclass, but this isn't really recommended. One way to deal with the fact that NSArray can only hold ids is to use respondsToSelector before calling a method on any of the objects in the array.
This solution isn't really a substitute for a good typing system, but it's a common practice to get around this limitation. Thankfully, generic support is getting added soon!
Objective-C is dynamically typed. You simply do not check for it.
Asking the audience on talks and in internet fora, the real danger that code will be shipped with a typing bug is minimal and by far lower than other sources of errors. Simply do not care about this.
Ask yourself: How could that happen without getting a runtime error at the very beginning of your next program run?

Why use "self" and what does it mean? [duplicate]

This question already has answers here:
What is self in ObjC? When should i use it?
(6 answers)
Closed 9 years ago.
So, I just started learning Objective-C and I've come across this "self" thing. I've only ever used C, but I think it's used in java too maybe? Can someone explain? Here's an example:
- (IBAction)digitPressed:(UIButton *)sender
{
NSString *digit = [sender currentTitle];
UILabel *myDisplay = [self display]; //why this?
}
Why isn't it just this?
- (IBAction)digitPressed:(UIButton *)sender
{
NSString *digit = [sender currentTitle];
UILabel *myDisplay = display; //why not like this?
}
display is a UILabel *
[self display], or self.display, refers to a property / method (property is just a shortcut for get/set method anyway) if you have something like this in the .h file
#property (weak, nonatomic) UILabel* display;
or
-(UILabel*)display;
Just display, or self->display refers to an instance variable. This is valid when you have declared an instance var like this:
#implementation MyClass {
UILabel* display;
}
If you have declared the property display in the .h file and haven't changed its default, the corresponding instance var will be _display (note the underscore), in which case the following will be the same:
self.display and self->_display
In this case it's an objective C messaging thing. When you see the brackets it's doing this:
[Object Message]
Basically self is the object and display is the message your sending it. Sending it a message is like a method call in another language, but a little different under the hood. So something like this:
[self doSomethingCool];
in objective C would translate to something like this in another language:
this.doSomethingCool();
of course if running a method on another object you'll replace self with that object like:
[myObject doSomethingCool];
in a lot of languages you don't really need to have the "this" in front of your method call, it's implied that if you don't include it you're running the method in the object you're working with. I got burned pretty early on when I started with something similar. I had a call to a datalayer method where you could save an object and it would give you an integer back. When I was saving the object I didn't put the self in front of the method call and it was essentially generating a new object and saving it and I wasn't getting the right integer back.
Using "self" just explicitly tells it "I'm using THIS object". Same thing with properties, I always use "self.MyProperty" instead of "MyProperty" because I want to be explicit and make sure I'm using the MyProperty of the object I'm working in. It's semi rare for a defect like that to hit you, where you expect to be using a certain object and the environment thinks you're using another, but man when you run into one it's a head scratcher because everything looks right.
The word self refers to the current object, which is your view controller instance in this case, and combining it with a method name, which is display, means you are sending the message display to self which is the view controller. This will invoke the method display declared in your view controller instance.
You might declare the display method in your view controller, for example:
- (UILabel)display
{
//your display method implementation returning UILabel instance
}
For the second one, it means you are referring to display variable. For example:
UILabel *display = [[UILabel alloc] init];
display is not a UILabel * - it might be a property with that type, or a method which returns a value of that type, but these a rather different things.
You need to go an read something about object oriented programming. The self in Objective-C is the current object reference, other OO languages call it this - both Java and C++ use that name. Understanding objects and methods is fundamental to using any of these languages.
There's a very good explanation of this here:
http://useyourloaf.com/blog/2011/02/08/understanding-your-objective-c-self.html
The key section for your question is the section on Objective-C 2.0 dot syntax:
Objective-C Dot Syntax
The dot syntax was introduced with Objective-C 2.0 and generates a lot
of debate. A number of experienced and long time Cocoa programmers
recommend avoiding it completely. Others such as Chris Hanson have a
different view about when to use properties and dot notation.
Whichever side of the argument you fall I guess the main thing is to
be consistent.
Anyway the main thing to understand about the dot syntax is that the
following two statements are doing the same thing:
self.timestamp = [NSDate date];
[self setTimestamp:[NSDate date]];
The dot is just a shortcut for the more traditional Objective-C method
call. Any time you see a dot you can replace it with the equivalent
square bracket method call syntax. It is important to understand
however that this is not the same as writing the following:
timestamp = [NSDate date]; Without the self object and the dot we are
no longer sending an object a message but directly accessing the ivar
named timestamp. Since this bypasses the setter method we will
overwrite the timestamp ivar without first releasing the old NSDate
object. We will also not retain the new object that we are assigning.
Both of these situations are bad!
Keep in mind that the examples were written without using ARC, so there's a lot of references to memory management, retain, release etc. It is however useful to see these examples so that you have some idea of what ARC is doing in the background.
In your example, you are not referring to the actual display property with [self display] you are in fact referring to an instance method of the "self" object which in this case is your UIViewController.

A NSZombie of an odd type

so i am getting a NSzombie and it says this
-[__NSArrayI _cfTypeID]: message sent to deallocated instance
Any idea what that is? assumably an array although i thought if it were an NS type it would say.
Yes — that'll be some type of array. Rather than being single classes, most of the foundation types are class clusters. So exactly how you initialise the array affects exactly which subclass of NSArray you get back.
The exact behaviour is undocumented and basically guaranteed to change over time but for example if you created an immutable array with less than a certain number of entries then the system might decide to return a single linked array and perform searches as simple linear searches. If you create one above the threshold then it might instead create an array that adds some sort of hierarchical logic for searching (or, more likely, contains the logic to create suitable hierarchical tables if the user starts trying to search the array).
Related lessons to learn:
never try to subclass a foundation class;
don't expect isMemberOfClass: to work properly;
don't even expect isKindOfClass: necessarily to be able to tell immutable from mutable versions of the foundation classes.
Apple needs a way to differentiate these classes and to flag them as private, so you end up with underscores and suffixes. In practice I think __NSArrayI is a vanilla immutable array.
Basically that means your NSArray object is already deallocated.
Something in Foundation.framework tried to access your NSArray's private method _cfTypeID and crashed.
And about question why there's _cfTypeID method in NSArray object. NSArray Core Foundation counterpart of CFArray. Two type's are interchangeable with "toll-free bridge".
So actually apple uses that method for internal uses.
If you want deeper understand of this. You can visit http://code.google.com/p/cocotron/source/browse/Foundation/NSArray/NSArray.m and this is Cocotron's implementation of NSArray. It is not same with the apple's implementation but still implementations are similar.

How to determine the structure of an iOS (id) object?

When I call a certain function from my iOS app, it returns an id data type. I can't see into this function so I don't know what it's doing or what the return type really is.
If I print it to console using NSLog("#"...) I get a string similar to this:
2012-01-18 19:03:08.915 HelloWorld[165:707] Key Press State.
Is there any way for me to determine the structure of this basic Id object? How would I go about getting a specific part of that response out, such as "Key press state". String parsing seems like a horrible idea, but maybe that's the only way. Perhaps the data really is just an NSString?
Thanks!
Try this:
NSLog(#"Mystery object is a %#", NSStringFromClass([mysteryObject class]));
If you look in <objc/runtime.h> you'll see methods for querying an object about its class, method selectors, ivars, etc. However, you don't usually want to do that, as it breaks encapsulation and can lead to you relying on implementation details that might change in the future, so be careful with it. You can read more here.

Resources