Assign value to NSUInteger in object after init - ios

I have a subclass of NSObject. In this class I have an NSUInteger declared like this:
#interface Deck : NSObject
- (id)initDecks:(NSUInteger)decks;
- (Card *)drawCard;
#property (nonatomic, assign) NSUInteger drawnCards;
In my implementation file, I have the following code:
#import "Deck.h"
#implementation Deck
- (id)initDecks:(NSUInteger)decks {
self = [super init];
if (self) {
self.drawnCards = 1;
}
return self;
}
- (BJCard *)drawCard {
self.drawnCards++;
return nil;
}
The number assigned to the NSUInteger (drawnCards) in the init method is set correctly, however, I am not able to change it later. I get no warnings or crashes in Xcode, but the number remains unchangeable. I have tried to do self.drawnCards++ and self.drawnCards = 10 etc, but nothing works. Any idea what might be wrong with my code? I am checking the value with:
NSLog(#"Value: %tu", self.drawnCards);

I believe the problem here is the objectiveC dot syntax. Because you are doing . with an object this is the equivalent to doing [self drawnCards]++ method call. The result of the method is incremented, not the drawnCards ivar. To do what you want you'll either need to do _drawnCards++ (access the iVar directly), or you'll need to do [self setDrawnCards:self.drawnCards++].

Related

iOS custom object initialization Error

I have a custom object ProductCategory.
.h file:
#import <Foundation/Foundation.h>
#interface ProductCategory : NSObject
#property int productCategoryId;
#property NSString *name;
#property NSArray *children;
#property int parentCategoryId;
- (id)initWithId:(int)productCategoryId name:(NSString*)name;
- (id)initWithId:(int)productCategoryId name:(NSString*)name children:(NSArray*)chidren parentCategoryId:(int)parentCategoryId;
#end
.m file:
#import "ProductCategory.h"
#implementation ProductCategory
- (id)init {
if((self = [super init])) {
self.parentCategoryId = 0;
}
return self;
}
- (id)initWithId:(int)productCategoryId name:(NSString*)name {
if((self = [super init])) {
self.productCategoryId = productCategoryId;
self.name = name;
self.parentCategoryId = 0;
}
return self;
}
- (id)initWithId:(int)productCategoryId name:(NSString*)name children:(NSArray*)chidren parentCategoryId:(int)parentCategoryId {
if((self = [super init])) {
self.productCategoryId = productCategoryId;
self.name = name;
self.children = chidren;
self.parentCategoryId = parentCategoryId;
}
return self;
}
#end
It's just a normal object, I have done this 100000 times. The problem is, sometimes the instance of this object returns "0 objects" and sometimes returns the correct object.
For example, if I do this ProductCategory *category = [[ProductCategory alloc]init]; sometimes it returns a ProductCategory instance, and sometimes it returns "0 objects" so I cannot assign any value to this object.
I guess it should be something really stupid but I don't see it.
The way to fix it:
Restart XCode.
Why it happen?:
Apple should answer this question.
It seems a garbage in memory issue after a period of time using XCode.
Workarounds if you get trap there
#HotLicks is right about the advising of use NSLog and po to be sure about the state of that object.
Also you can invoke methods and read properties of the object in question by using expression command in debugger window after a breakpoint.
zevarito is on the right track. A bit more seems to solve the long-irritating problem:
Close the project.
Xcode -> Window -> Projects
For the project in question (and all others is probably a good housecleaning idea), click Derived Data -> Delete.
Close Xcode.
Close Simulator.
Restart Xcode and resume what you were doing.

Can an Objective-C object remove itself in its method (ARC is enabled)?

In some reason, I have to use a design pattern that an object remove itself from its container, consider the following code(ARC is enabled, LCDObject is an object class, LCDContainer is a container class), in the whole program, object 's reference count is always 1 until it is removed from the container(reference count become 0), as comment 2 mention, when [_container removeObject:self] return, the object's reference count is 0, it is dealloc, right?, but the process is still in the object's method -- "removeFromContainer", what would happen? Does the following code would be execute successfully? Does "removeFromContainer" can return successfully?
I run this code in Xcode, the "NSLog" in "removeFromContainer" can be invoked successfully, but I can't figure out why...
//-------------------------------------------------------------
#import <Foundation/Foundation.h>
#interface LCDContainer : NSObject
#property (strong, nonatomic) NSMutableArray *objects;
- (void)removeObject:(id)object;
- (id)addObject:(id)object;
#end
#implementation LCDContainer
- (id)init {
self = [super init];
if (self) {
_objects = [[NSMutableArray alloc] init];
}
return self;
}
- (id)addObject:(id)object {
[_objects addObject:object];
return object;
}
- (void)removeObject:(id)object {
[_objects removeObject:object];
}
#end
//-------------------------------------------------------------
#interface LCDObject : NSObject
#property (weak, nonatomic) LCDContainer *container;
- (id)initWithContainer:(LCDContainer*) container;
- (void)removeFromContainer;
#end
#implementation LCDObject
- (id)initWithContainer:(LCDContainer *)container {
self = [super init];
if (self) {
_container = container;
// (1) add the object to the Container, now its reference count is 1
//
[container addObject:self];
NSLog(#"add to container.");
}
return self;
}
- (void)removeFromContainer {
// (2) remove the object from the Container, now its reference count is 0,
// the object is delete, does the following "NSLog" would be invoked successfully?
//
[_container removeObject:self];
NSLog(#"remove from container.");
}
#end
//-------------------------------------------------------------
int main(int argc, const char * argv[]) {
#autoreleasepool {
LCDContainer *container = [[LCDContainer alloc] init];
[[LCDObject alloc] initWithContainer:container];
[[[container objects] objectAtIndex:0] removeFromContainer];
}
return 0;
}
I've not tried your code but I suspect it will work. sapi's suggestion (adding a breakpoint or NSLog on dealloc) is a good one to confirm, though.
Thee are two ways that ARC could be doing this. You can check the assembler if you're really interested.
The simplest is to assume that it's using autorelease, that is, when an object is removed from your container it gets added to the autorelease pool and is released (and dealloced) at the end of the current run loop.
The other way is to consider where ARC adds its retains and releases. This question notes that your remove method really looks like this:
- (void)removeObject:(id)object {
[object retain];
[_objects removeObject:object];
[object release];
}
The call to removeObject: may well have the same logic. This means that object does not get released as soon as the removeObject: call is completed; the object lifecycle is almost certainly (slightly) longer than that.

Objective C: allow properties in category via custom root class

There are many questions concerning the category-properties problem.
I know some possibilities to address this:
use a singleton registry
objc_setAssociatedObject and objc_getAssociatedObject
From my point of view both is not clean since the memory allocated is never cleared when the object that created such properties is deallocated.
Categories are a good way to keep code clean and dynamically add functionality to already existing classes. They help to group functionality and to distributed implementation work among more developers.
The bad about categories is the missing storage.
I came across this problem several times now and I'm wondering whether the following would address this problem in an clean way that also takes care about the memory and if there are any problems that I can't see right now.
There is one restriction, that I can ignore since I'm working as a framework developer: I'm able to create my own root class that all my other classes can inherit from.
First of all declare the new root object:
#interface RootObject : NSObject
- (void)setRuntimeProperty:(id)runtimeProperty forKey:(id<NSCopying>)key;
- (id)runtimePropertyForKey:(id)key;
#end
With the corresponding implementation:
#import "RootObject.h"
#interface RootObject ()
#property (readwrite) NSMutableDictionary *runtimeProperties;
#end
#implementation RootObject
#synthesize runtimeProperties = _runtimeProperties;
- (id)init {
self = [super init];
if (self)
{
_runtimeProperties = [[NSMutableDictionary alloc] initWithCapacity:1];
}
return self;
}
- (void)dealloc {
[_runtimeProperties release];
_runtimeProperties = nil;
[super dealloc];
}
- (id)runtimePropertyForKey:(id)key {
return [self.runtimeProperties objectForKey:key];
}
- (void)setRuntimeProperty:(id)runtimeProperty forKey:(id<NSCopying>)key {
if (key)
{
if (runtimeProperty)
{
[self.runtimeProperties setObject:runtimeProperty forKey:key];
}
else
{
[self.runtimeProperties removeObjectForKey:key];
}
}
}
#end
By using this RootObject instead of NSObject it should be very easy to add a "property" to a category on a class. Consider having some class MyClass
#interface MyClass : RootObject
// some interface here
#end
When implementing a special behavior on top of this class you are now able to add a property like this:
#interface MyClass (specialBehavior)
#property (nonatomic, retain) NSString *name;
#property (nonatomic, copy) NSDate *birthday;
#end
With corresponding implementation:
#implementation MyClass (specialBehavior)
#dynamic name;
- (NSString *)name {
return [self runtimePropertyForKey:#"name"];
}
- (void)setName:(NSString *)name {
[self setRuntimeProperty:name forKey:#"name"];
}
#dynamic birthday;
- (NSDate *)birthday {
return [self runtimePropertyForKey:#"birthday"];
}
- (void)setBirthday:(NSDate *)birthday {
[self setRuntimeProperty:[birthday copy] forKey:#"birthday"];
}
#end
Such an implementation could KVO compatible as well by just adding the necessary calls in the setter method.
Very straight forward, but I'm wondering whether I missed something important? (E.g. very very bad runtime performance having many such declared properties or using many of these objects)
This is effectively the same as objc_setAssociatedObject and objc_getAssociatedObject, which do release memory when the object is deallocated (depending on the association type). I would guess they also have much lower overhead than your suggested code.

Manipulating properties in init that are set up by a sub-class in Objective-C

I have an abstract interface in Objective-C where every sub-class needs to set up a property and then do the exact same thing with that property at the end of init. I'm trying to avoid duplicated code with something like this:
Interface File
#interface Shape : NSObject
#property (nonatomic) PropertyType *prop;
- (id)init;
- (void)initProperty;
#end
Implementation File
#implementation Shape
- (id)init
{
if(self = [super init]) {
[self initProperty];
[prop doSomething];
}
return self;
}
- (void)initProperty
{
}
#end
My problem is that every sub-class will need a different set of parameters passed to initProperty in order to implement the method correctly:
#implementation Rectangle
- (void)initPropertyWithRect:(CGRect)rect
{
prop = [RectangleStuff rectangleWithRect:rect];
}
#end
#implementation Circle
- (void)initPropertyWithRadius:(CGFloat)radius
{
prop = [CircleStuff circleWithRadius:radius];
}
#end
Is there a clean way to do what I'm trying to do in Objective-C? So far, my options seem to be:
Create a "property bag", and just pass around an NSDictionary.
Duplicate the [property doSomething]; code in every subclass.
Somehow pass in a factory object to init, and have the factory object create prop. This approach seems the cleanest, but I'd need the factory object to keep the rect and/or radius as internal state somehow, and that doesn't seem clean to me.
Any thoughts?
I would probably choose #2 (to keep it simple). If the property is only set once
(in the subclass init method), you could override the property setter method in the
superclass, and do the additional stuff there.
Untested code:
- (void)setProp:(PropertyType *)prop
{
_prop = prop; // (Assuming ARC)
[_prop doSomething];
}
First, I feel obligated to mention that your init function should not do anything besides initialize the object. That said, every rule has a time and a place to be broken, so I'll offer what suggestions I can.
Your init function is no different than any other function. You can do things before and after you call super. While generally discouraged, this would be a good place to do it. Your init in your subclass would now look like this:
- (id)init
{
self.myProperty = value;
self = [super init];
if (self) {
// more init stuff
}
return self;
}
I ended up using a variant of what was suggested in the other two answers:
Shape.h
#interface Shape : NSObject
#property (nonatomic) PropertyType *prop;
- (id)initWithProperty:(PropertyType *prop);
#end
Shape.m
#implementation Shape
- (id)initWithProperty:(PropertyType *)prop
{
if(self = [super init]) {
_prop = prop;
[_prop doSomething];
}
return self;
}
#end
Rectangle.m/Circle.m
#implementation Rectangle
- (void)initWithRect:(CGRect)rect
{
return [self initWithProperty:[RectangleStuff rectangleWithRect:rect]];
}
#end
#implementation Circle
- (void)initWithRadius:(CGFloat)radius
{
return [self initWithProperty:[CircleStuff circleWithRadius:radius]];
}
#end

arrow operator in objective-c

I have a question, here's the code:
#interface MyFoo : NSObject {
NSString *nameStr;
}
#end
#implementation MyFoo
- (id)init {
self = [super init];
if (self) {
self->nameStr = [#"some value of the string that is set right into the private ivar" copy];
}
return self;
}
#end
The question is: ignoring all the C++ rules, ignoring memory dump vulnerability, why exactly I shouldn't use such arrow operator syntax?
Is there somewhere in Apple documentation a rule which says that it's incorrect because in future class may be represented differently than a pointer to a struct in runtime etc. ?
Thanks in advance!
The use of self->someIvar is identical to someIvar. It's not wrong but it's not needed either.
The only time I use the arrow notation is in an implementation of copyWithZone: so I can copy each of the ivars that don't have properties.
SomeClass *someCopy = ...
someCopy->ivar1 = ivar1; // = self->ivar1
someCopy->ivar2 = ivar2; // = self->ivar2
Where are you seeing anything that says you shouldn't use such arrow operator syntax?
Using arrow notation on just the ivar name to access a property will not guarantee they will be retain, assign or etc ...
Because you are directing accessing an ivar and not calling and setter ou getter method used in properties.
Example:
#interface MyFoo : NSObject {
}
#property(nonatomic,retain) NSString *nameStr;
#end
#implementation MyFoo
- (id)initWithString:(NSString *)name {
self = [super init];
if (self) {
self->nameStr = name; // will not be retained
}
return self;
}
#end
For ivar variables as already be answer there`s nothing wrong.
Using the arrow notation isn't incorrect, and there is a difference between using the arrow and the dot notation.If you use the arrow operator you access to the instance variable, if you use the dot operator you access to the property.
It doesn't work like C structs where you use the arrow notation to access to a member of a struct pointed, and dot notation to access the struct members.
So I would make a significative example:
#property (nonatomic, strong) NSString *text;
In .m file:
- (void)setText:(NSString *)string {
NSLog(#"Accessing property");
self->text = string; // let's suppose that text is not synthesized
}
If you use the dot notation , then you access to the property and it would print "Accessing property".But this hasn't to do with C structs syntax.

Resources