Can't 'nil' a variable xcode - ios

Trying to 'nil' some double variables... but getting the 'Assigning to 'double' from incompatible type 'void *' error...
This is my properties (trying to make a variable type class, that holds global vars so they can be accessed and changed from anywhere in the app):
#property (nonatomic) CGPoint lastP;
#property (nonatomic) double brushR;
#property (nonatomic) double brushG;
#property (nonatomic) double brushB;
#property (nonatomic) double brushW;
#property (nonatomic) double brushO;
#property (nonatomic) BOOL mouseSwiped;
then I synthesis like so:
#Synthesis lastP;
#Synthesis brushR;
etc, etc,
and when I do a cleanup method (as I'm exiting the view and going back to a menu) and try and nil the vars so they can be deallocated via arc
brushR = nil;
brushG = nil;
lastP = nil;
etc, etc
I get the error I stated above.
Is it easier to just use [view removefromsuperview] in the parent viewcontroller (as all this information is going into a containerView INSIDE of a view controller (that's the way it needs to be, can't get around this)) and will that kill all the variables from the above calss? or do I need to nil them manually?
if I can just use removefromsuperview (from a parent class) (eg, I have a view controller and then a container view inside that controller, when a button is pushed in the PARENT controller, the app uses [childcontroller removefromsuperview]) will that 'kill' ALL objects being used by the childview (as I have a uiImage inside the childview view and it didn't seem to clear the image it was holding from memory when I tried this method).
if I have to nil my vars (and not just nuke the view and remove it from the hirachy) why isn't it letting me do this?
I really hope I'm understandable.

Is it easier to just use [view removefromsuperview] in the parent viewcontroller (as all this information is going into a containerView INSIDE of a view controller (that's the way it needs to be, can't get around this)) and will that kill all the variables from the above calss? or do I need to nil them manually?
If you use ARC, you don't need to do a cleanup. Runtime will do that for you.
I have a uiImage inside the childview view and it didn't seem to clear the image it was holding from memory when I tried this method
It will be released as long as there are no other strong references to it.

You can never nil primitives only pointers. To explain. nil is of type "void *" and you can not assign void * to type float, double etc. you can only assign void * to pointer types. Since a pointer is an address to some memory when you assign nil to the pointer you are pointing the pointer to some memory space that are reserved for nil.

You cann't do this. You can only set nil to pointers. Primitives cann't fill with nil/NULL. You may assign simple zero in these place.

For id type objects you use nil. Otherwise for void * (ie a C-style pointer) you can use NULL/ nil
Use brushR = 0; then it should be fine.

Since Double is primitive type ,
therefore ,we cannot set it as nil.
nil or Nil can be set to ObjectType Variable.

Related

Best way to pass CGFloat by reference to another class

In ClassA, I have a CGFloat value x that I want to pass by reference to ClassB such that if I make a change to the CGFloat in ClassA, it will be reflected in the reference to x in ClassB. Also, when I pass it to ClassB, I want to store it as a property.
I've thought about using a CGFloat pointer, but I'm struggling to figure out the proper syntax to make it a property:
#property(nonatomic) CGFloat *x;
And then to dereference it:
self->x
I thought about using NSNumber but there is no way to set the value using NSNumber such that it will update in ClassB. I thought about giving up and making a wrapper class to store the CGFloat, but this seems like overkill.
What is the best pattern to go about doing this?
I thought about giving up and making a wrapper class to store the CGFloat, but this seems like overkill.
The advantage of this approach is safety, you create an object, both classes reference it, and ARC takes care of the memory management.
The class is easy to define, for example:
#interface ABShare1 : NSObject
#property CGFloat x;
#end
#implementation ABShare1
#end
(in a .h & .m file – same for other examples)
A class using this would be something like:
#implementation ClassA
{
ABShare1 *one;
}
...
one = ABShare1.new; // somewhere in initialisation
...
... one.x = 42; ... z = one.x * 24; ...
Note: the above stores the ABShare1 reference in a private instance variable, you can store it in a property if you wish but there is no need to.
You can call a method on another class passing the object, e.g.:
ClassB *myB;
...
[myB using:(ABShare1 *)sharedVariable];
and that other class can keep the reference as long as it requires, memory management is automatic.
I've thought about using a CGFloat pointer
This is the standard C (a subset of Objective-C) way of "passing by reference".
You can store a CGFloat * in a property, all "object" valued properties in Objective-C just store pointers (e.g. #property NSString *name; stores a pointer to an NSString object).
You must create the variable that the CGFloat * references, the equivalent of new or alloc/init in Objective-C. You can use the address of a variable, e.g. something like:
CGFloat actualX;
CGFloat *x = &actualX;
but you have to manually ensure that the referenced variable, actualX, lives at least as long as its pointer, stored in x, is in use – failure to do that results in a dangling pointer.
The other option is to dynamically allocate the storage, the direct equivalent of new, e.g. something like:
CGFloat *x = malloc(sizeof(CGFloat));
However you are now responsible for determining when the storage is no longer required and releasing it (using free()).
The first solution to you is "overkill" – maybe because while you are freed from concerns over memory management you don't get a "variable" but two functions/methods to get/set a value.
The second solution is closest to feeling like a "variable", you just use *sharedVariable rather than sharedVariable. However while the manual memory management required is standard for C programmers, it is not for Objective-C programmers.
A third approach mixes the two building on how structures (struct) in C can be used: to share a collection of variables rather than share each one individually by address, instead define a struct with a member for each variable, allocate one and share its address, something like:
typedef struct ABShare
{ CGFloat x;
CGFloat y;
} ABShare;
ABShare *one = malloc(sizeof(ABShare));
one->x = 42;
one->y = 24;
The above has the same memory management issues as the second solution, but we can convert it to a very close Objective-C equivalent:
#interface ABShare : NSObject
{
#public // required
CGFloat x;
CGFloat y;
}
#end
#implementation ABShare
#end
Note: Objective-C classes are effectively implemented using structs, indeed the first Objective-C compilers actually translated them into C struct code.
Using this is very close to the C:
ABShare *one = ABShare.new;
one->x = 42;
one->y = 24;
Same "variable" look as C but with automatic memory management.
This last scheme is essentially how Objective-C manages sharing variables when a block is created – all the local variables accessed by the block are moved into a dynamically allocated object/struct and the variables then accessed using ->.
Which is best in Objective-C? The first and the third are both "Objective-C" style, the second is usually avoided accept when interacting with C APIs. Of the first and third pick whichever feels "right" semantically, rather than concerns over performance, to you. HTH
[NSMutableData dataWithLength:sizeof(CGFloat)] and cast mutableBytes to CGFloat*
You can implement getter and setter of property #property(nonatomic) CGFloat x -without pointer

insert text from textview to string return NSMallocBlock in the string objective c

I have a textview that user can edit, when I try to insert the text from the textview to a local property from type Nsstring, I got in this property NSMallocBlock. what is the reason? thank you!
this is the defintaion of cartItemComment:
#property (nonatomic, assign) NSString * cartItemComment;
and this is the code:
CartItem *cartItem = [[CartItem alloc]init];
cartItem.cartItemComment = itemRequestText.text;
cartitem is a object that have a property cartItemComment, after those lines, I got NSMallocBlock in cartItemComment.
another problem, i can get a weird string like this:
assign property attribute applies to primitive types, it does nothing with the object reference. When an object is assigned to this property, it is deallocated (if it is not retained by some other object), and all you have left is a pointer to the memory where it once was. Never use assign to store objects.
weak is similar to assign, with the only difference that when the object referenced by this property is deallocated (retain count reaches zero), it is set to nil, so you would never have a pointer to garbage memory.
strong retains the object and prevents it from being deallocated.
Your property should be declared like so:
#property (nonatomic, strong) NSString *cartItemComment;

Non-Object Attribute in Core Data, transient properties

Feel lost after reading this section: A Non-Object Attribute
According to the Basic-Approach also contained in above link, I should have 2 attributes in my custom-code when handling "transient properties":
1st attribute, for the actually-wanted (un-supported) custom type => transient attribute
2nd attribute, for shadow-representation (concrete supported) type => persistent attribute
......
My reading was very enjoyable, until reached "A Non-Object Attribute" section, which puzzle me deeply, as quoted below:
...When you implement the entity’s custom class, you typically add an instance variable for the attribute. ...
《 OK, I can follow this...make an iVar is no big deal》
If you use an instance variable to hold an attribute, you must also implement primitive get and set accessors
《 OK, I know how to do primitive-accessor. why need them? because internal-optimized-storage inside MO can be efficiently used, I guess.》
#interface MyManagedObject : NSManagedObject
{
 NSRect myBounds; // I assume this suppose to be the **transient attribute**
}
#property (nonatomic, assign) NSRect bounds; // I assume this is the **persistent attribute**
#property (nonatomic, assign) NSRect primitiveBounds; // because complier forces me to implement below primitive-accessors ?
#end
- (NSRect)primitiveBounds
{
return myBounds; // accessing iVAR storage for **transient attribute**? I hope so
}
- (void)setPrimitiveBounds:(NSRect)aRect
myBounds = aRect; // accessing iVAR storage for **transient attribute**? I hope so
}
From here down below, I have... too many ???????????? unsolved
- (NSRect)bounds
{
[self willAccessValueForKey:#"bounds"]; //KVO notice of access **persistent attribute**, I guess
NSRect aRect = bounds; //will this invoke primitive-Getter ???
[self didAccessValueForKey:#"bounds"];
if (aRect.size.width == 0) //bounds has not yet been unarchived, Apple explained
 {
NSString *boundsAsString = [self boundsAsString]; // unarchiving pseudo method, I guess
if (boundsAsString != nil) //if that value is not nil, transform it into the appropriate type and cache it...Apple explained.
{
bounds = NSRectFromString(boundsAsString); //will this invoke primitive-Setter???
}
}
return bounds;
}
I put my final question list here:
1, do I STILL need to have 2 attributes to handle NON-Object-Attribute, transient attribute and persistent attribute?
2, how can iVar "myBounds" be represented/connected with "#property bounds"? Is this "#property bounds" the modeled-property in a MOM?
3, what is the purpose of implementation of primitive-accessor here? for enforcing me write KVO (will...did...) methods pair? for transferring values (in and out) between iVar "myBounds"and "#property bounds"?
4, in this line of code
bounds = NSRectFromString(boundsAsString); //will this invoke primitive-Setter???
is primitive-Setter called OR public/standard-Setter gets called? Why?
In iOS, there are the very convenient NSStringFromCGRect and CGRectFromNSString functions. Why not just use those and store a string?
Your questions:
Yes, you need the 2 attributes, as explained in the documentation.
Yes, this is based on the managed object model. The primitiveX name for x is generated / interpreted automatically.
You need the primitive accessor methods here to make it KVC - which is not the case with primitives.

Obj-C Setters returning null

I am making a simple app and this piece of code has been giving me issues.
Here is my property.
In ConverisonCalculator.h
#property (strong, nonatomic)NSString *startingUnit;
In Viewcontroller.m I am using this code and everytime I NSLog it I am getting (null)
_calculator.startingUnit = #"FPS";
Also here is my lazy instantiation of the object.
- (ConversionCalculator *)calculator{
if (!_calculator) _calculator = [[ConversionCalculator alloc]init];
return _calculator; }
I hope this is enough for you to answer my question. I am not override the default setter either.
Here is my logging.
NSLog(#"%#", [_calculator startingUnit]);
_calculator.startingUnit = #"FPS";
This is not using your property. This is direct access to the instance variable, so your lazy loading code is never called.
If you define properties, always access them through the property:
self.calculator.startingUnit = #"FPS";
Otherwise, you might as well be using instance variables. The only exception is inside the accessor methods themselves, or in init or dealloc methods (in some cases).

EXC_BREAKPOINT: Message sent to deallocated instance

I get the above message in XCode 4.6. I've done a pretty thorough search and but nothing seems to match the exact circumstances surrounding my issue. Admittedly, I'm relatively new to iOS dev, and memory-management has never been my strong suit, but this just has me completely miffed.
I have an instance variable theLink which is defined in the class Game as follows:
#interface Game : NSObject
// Class objects
#property(nonatomic,retain) NSMutableArray *queryItems;
#property(nonatomic,retain) NSMutableArray *theArray;
#property(nonatomic,retain) NSString *theLink;
#property(nonatomic,retain) NSString *thePath;
theLink is set in the makeGame method which is called in the method initialiseGame in my view controller:
- (void) initialiseGame
{
bool gameCreated = FALSE;
while (!gameCreated)
{
gameCreated = [theGame makeGame:#"ptl"];
}
[loadingIndicator stopAnimating];
[loading setText:#"Tap to Start"];
[self performSelector:#selector(setLabels) withObject:nil afterDelay:0.0];
}
(Note: the performSelector afterDelay is used to allow the view to update before continuing. Bit of a hack but I couldn't work out a better way!)
The app then loads the game, and when the user taps the screen to start, the next method which is called from the view controller is:
- (void) setupLink
{
...
for(int i=0; i<[theGame.theLink length]; i++) {
...
}
}
It is on this reference to theGame.theLink where I'm am getting the crash.
What has me most confused is that if I call theGame.theLink from inside the initialiseGame method, it is displays correctly, and also calling any other variable from the Game class (such as thePath or theArray works perfectly, so theGame object has not been deallocated in it's entirety, only the variable theLink.
It seems to me that the variable is being deallocated somewhere as the view controller is being updated. I haven't released the variable, and can't work out why only this variable is being deallocated. As I said at the start, memory-management is not my strength!
Any help/ideas would be hugely appreciated. Let me know if you require any more details.
Thanks heaps,
Andrew
EDIT: Setting of theLink within makeGame
- (bool) makeGame:(NSString*)gameType
{
...
[self getLink];
}
- (void) getLink
{
...
if (... && ((arc4random() % 10) > 8))
{
theLink = #"Animals";
}
}
There are many different ways theLink may be set, depending on random numbers and other factors. This is the most basic form which simply sets it to a static string. It doesn't matter how theLink is set or what it is set to, the program always crashes at the same point.
If theLink is being set to the parameter being passed to it ,#"ptl" or some similar temporary string, it will give you a problem, because it is just a pointer pointing at the current location that is holding #"ptl". After the makeGame method is completed, your system will assume that it is all done with #"ptl" and just free it up.
When you make an #"stringwhatever" in your code, it is supposed to be the equivalent of making an NSObject that is an immutable literal instance of #"stringwhataver". It should, in theory handle all the reference counting in a nice way, but when you are doing your own memory management, there are so many ways to lose count of your references.
There's a pretty simple rule to follow. If you've declared properties, access them via the property. To do otherwise (as you are doing above, with theLink = ...) bypasses all of the memory management built into the property accessors.
self.theLink = ...
Would have solved this problem under MRC. Switching to ARC has "solved" your problem without you understanding the root cause.

Resources