Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Ja Di ksw

macrumors 65816
Original poster
Apr 9, 2003
1,313
8
Hi everyone, should hopefully be an easy question (teaching myself Objective C as I go).

I would like to send a method to an object (Cell) which returns a different object (Waste), and then deletes the reciever (Cell). Here is what I'm looking at so far:


Code:
#import "Cell.h"

#import "Waste.h"


@implementation Cell


@synthesize.......
other methods.....




- (Waste *) die                    // Send a method to an instance of class "Cell", causing a new object of class "Waste" to be made, then causing the Cell instance to "die"

{

    Waste *newWaste = [[Waste alloc] init];            // Create a new object, "newWaste", of class Waste    ARC Semantic Issue: No known class method for selector 'alloc'

    newWaste.wasteEnergy = (0.1 * cellEnergy);         // Set the energy of "newWa" to 10% what the Cell's energy is

    newWaste.wasteXCoordinate = cellXCoordinate;       // Set the X coordinate of "r" to the Cell's X coordinate

    newWaste.wasteYCoordinate = cellYCoordinate;       // Set the Y coordinate of "r" to the Cell's Y coordinate

    newWaste.wasteExcreted = NO;                       // Variable saying if the Waste is to be excreted set to "NO"

    return newWaste;                                   // Return the new waste object

    self = nil;                                        // Have the Cell "die"  ARC Semantic Issue: Cannot assign to 'self' outside of a method in the init family

};

I've put the two issues that come up behind the comments so you know where the problems are, but they're:
ARC Semantic Issue: No known class method for selector 'alloc'
and
ARC Semantic Issue: Cannot assign to 'self' outside of a method in the init family

Could someone tell me why this is happening and how to fix it? I had thought it was straightforward to do:
Class *newInstance = [[Class alloc] init];
and that this could be done inside a method so you can return the instance. And I had read that self = nil; was the normal way for releasing objects with ARC.

Thank you for any help!
 
An object does not release it self, the owner (retainers actually) of that object releases it.

Anything after the 'return' is not executed.

Waste needs to be a subclass of something to have alloc available. At least of NSObject. Lets see your .h file content.
 
...
I would like to send a method to an object (Cell) which returns a different object (Waste), and then deletes the reciever (Cell). ...

Please explain exactly why you want to do this. That is, explain what the overall program you're writing is intended to do, what a Cell object does within the program, and what a Waste object does within the program.

Given your brief description and the code fragment, I suspect you misunderstand how objects work. The described approach won't work in any object-oriented language, because the destruction of an object isn't up to the object itself, but to any object that refers to it. An object can only be deleted when no other objects refer to it. If that doesn't make sense, you need to study object lifetime and how to design with objects.

You definitely misunderstand how the 'return' statement works. No code after an unconditional return will ever execute. Ever. The purpose of 'return' is to immediately return execution to the caller. When that happens, no further code in the function or method can possibly execute. Any code after an unconditional return is unreachable and unexecutable.


Without seeing Waste.h and possibly Cell.h, there's no way to diagnose the cause for this error message:
Code:
No known class method for selector 'alloc'
The reason for the other error message should be clear: you can't assign nil to self outside an init method. If you don't understand why, then you need to study init methods again.


What you've posted is known as an "XY Problem":
.. How do I use X to accomplish Y?
http://perl.plover.com/Questions3.html

http://www.perlmonks.org/index.pl?node_id=542341
.. You want to do X, and you think Y is the best way of doing it.
.. Instead of asking about X, you ask about Y.

That is, you've decided that deleting the receiver Cell is the best way of doing something. Deleting the receiver is your Y. Unfortunately, you haven't described any X, or why you want to actually do this. So instead of asking about X, you ask about Y (how to delete the receiver).
 
So, I've somewhat solved the problem (at least in it not giving me any more errors), but from reading your post I'm guessing it's either not right or there are other more serious underlying problems.

Please explain exactly why you want to do this. That is, explain what the overall program you're writing is intended to do, what a Cell object does within the program, and what a Waste object does within the program.

I want the overall program to be similar to a simulation of Braitenberg vehicles, though with each vehicle doing a little more than sense->move. The Cell object was going to contain the variables and methods for a Braitenberg vehicle (XY position, for example). The Waste object is similar, though with fewer methods / variables.

Given your brief description and the code fragment, I suspect you misunderstand how objects work. The described approach won't work in any object-oriented language, because the destruction of an object isn't up to the object itself, but to any object that refers to it. An object can only be deleted when no other objects refer to it. If that doesn't make sense, you need to study object lifetime and how to design with objects.

I had someone explain this to me and read up on it, so I think I understand it now.

You definitely misunderstand how the 'return' statement works. No code after an unconditional return will ever execute. Ever. The purpose of 'return' is to immediately return execution to the caller. When that happens, no further code in the function or method can possibly execute. Any code after an unconditional return is unreachable and unexecutable.

I didn't realize that, and since I thought I had to release the object and wanted something returned from it before its release, I assumed the return could come first.


Without seeing Waste.h and possibly Cell.h, there's no way to diagnose the cause for this error message:
Code:
No known class method for selector 'alloc'
The reason for the other error message should be clear: you can't assign nil to self outside an init method. If you don't understand why, then you need to study init methods again.

No problem, I have Waste as another class and it's able to work now (and makes other things easier to handle as well)

What you've posted is known as an "XY Problem":
.. How do I use X to accomplish Y?
http://perl.plover.com/Questions3.html

http://www.perlmonks.org/index.pl?node_id=542341
.. You want to do X, and you think Y is the best way of doing it.
.. Instead of asking about X, you ask about Y.

That is, you've decided that deleting the receiver Cell is the best way of doing something. Deleting the receiver is your Y. Unfortunately, you haven't described any X, or why you want to actually do this. So instead of asking about X, you ask about Y (how to delete the receiver).

The why I want to delete something is that this particular Braitenberg vehicle doesn't exist anymore, so the instance of it isn't needed. i.e. = how do I get rid of it.

Changing Waste to be a subclass of NSObject and getting rid of the last line (self = nil) looks like it works, though. I can make a Waste object fine and the Cell object should be released since it has no more owners.
 
So, I've somewhat solved the problem (at least in it not giving me any more errors), but from reading your post I'm guessing it's either not right or there are other more serious underlying problems.



I want the overall program to be similar to a simulation of Braitenberg vehicles, though with each vehicle doing a little more than sense->move. The Cell object was going to contain the variables and methods for a Braitenberg vehicle (XY position, for example). The Waste object is similar, though with fewer methods / variables.



I had someone explain this to me and read up on it, so I think I understand it now.



I didn't realize that, and since I thought I had to release the object and wanted something returned from it before its release, I assumed the return could come first.




No problem, I have Waste as another class and it's able to work now (and makes other things easier to handle as well)



The why I want to delete something is that this particular Braitenberg vehicle doesn't exist anymore, so the instance of it isn't needed. i.e. = how do I get rid of it.

Changing Waste to be a subclass of NSObject and getting rid of the last line (self = nil) looks like it works, though. I can make a Waste object fine and the Cell object should be released since it has no more owners.


what ever class / object allocated the class "owns" it (it's more in-depth then that but for simplicity sake just roll with it). if you are allocating say "mySomethingObject" of type "Something *", in say your "MainViewController"

Code:
#import "Something.h"

@interface MainViewController : NSObject  //or whatever subclass

@property Something *mySomethingObject;

@end

...
@implimintation MainViewController

some code...

self.mySomethingObject = [[Something alloc] init];

more code...
@end

the "MainViewController" "owns" that object, and references the setter & getters by using "self.mySomethingObject". "self" in this case is the "MainViewController". to "kill" or dereference that object it would need to send a message and set the value to "nil"

Code:
 self.mySomethingObject = nil;

from an objective-c standpoint, "self" is a special typedef that refers to that specific instance of an object. a simple way of looking at it (possibly the wrong way, but easiest to understand) is any code being performed is being performed on "self" at that specific time. to clarify by using to the "MainViewController" as an example, all the code being executed is essentially being executed on "self" or "me" because "i" have all the code information that makes the class that creates me. this is why we use "[self someMethod]" when want to call instance methods that reside in our own .m file. you are telling (sending a message to) yourself to do something.

when you allocate your "mySomethingObject" from your "Something" class. "self" is still "MainViewController", BUT during the creation of "mySomethingObject, a reference to "self" inside the "Something" class code, refers to what ever instance (specific individual creation) of that class (mySomethingObject in this case).

"self" is always (ok, almost always, but i think you should get the point from here) the object doing the work and making changes. so when you tell a label to change the color of it's font, you aren't changing the color. the label is the one changing the color for you, per your request. so in that case the label is it's own "self" inside of it's own class file code.

hope that helps, because it's an important thing to understand when working with objective-c. just think of you as a person in the real world. you do things for your"self" and ask other people to do things for you, and they them "self" do the work you ask.
 
Last edited:
That makes sense, thanks for the example

what ever class / object allocated the class "owns" it (it's more in-depth then that but for simplicity sake just roll with it). if you are allocating say "mySomethingObject" of type "Something *", in say your "MainViewController"
...
 
Last edited by a moderator:
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.