[MyClassName copyWithZone:]: unrecognized selector sent to instance? - ios

I just implemented my class
#interface ExampleNestedTablesViewController ()
{
NSMutableArray *projectModelArray;
NSMutableDictionary *sectionContentDictionary;
}
- (void)viewDidLoad
{
[super viewDidLoad];
ProjectModel *project1 = [[ProjectModel alloc] init];
project1.projectName = #"Project 1";
ProjectModel *project2 = [[ProjectModel alloc] init];
project2.projectName = #"Project 2";
if (!projectModelArray)
{
projectModelArray = [NSMutableArray arrayWithObjects:project1, project2, nil];
}
if (!sectionContentDictionary)
{
sectionContentDictionary = [[NSMutableDictionary alloc] init];
NSMutableArray *array1 = [NSMutableArray arrayWithObjects:#"Task 1", #"Task 2", nil];
[sectionContentDictionary setValue:array1 forKey:[projectModelArray objectAtIndex:0]]; // **this line crashed**.
}
}
Here is my Project Model
#interface ProjectModel : NSObject
typedef enum
{
ProjectWorking = 0,
ProjectDelayed,
ProjectSuspended,
} ProjectStatus;
#property (nonatomic, assign) NSInteger idProject;
#property (nonatomic, strong) NSString* projectName;
#property (nonatomic, strong) NSMutableArray* listStaff;
#property (nonatomic, strong) NSTimer* projectTimer;
#property (nonatomic, assign) ProjectStatus projectStatus;
#property (nonatomic, strong) NSMutableArray* listTask;
#property (nonatomic, assign) NSInteger limitPurchase;
#property (nonatomic, strong) NSDate* limitTime;
#end
And the output is:
SDNestedTablesExample[1027:c07] -[ProjectModel copyWithZone:]: unrecognized selector sent to instance 0x7562920.
I didn't know which problem. Can you help me ?

Look at the docs for NSMutableDictionary setObject:forKey: (note you should use setObject:forKey:, not setValue:forKey:). Notice the expected type for the key. It must be of type id<NSCopying>. This means the key must conform to the NSCopying protocol.
Since your keys are of type ProjectModel, the error is complaining since your ProjectModel class doesn't implement the required method of the NSCopying protocol - copyWithZone:.
Are you sure you want to use a ProjectModel object as the key? Doing so also means you need a sane implementation of the isEqual: and hash methods, in addition to copyWithZone.
The solution is to update your ProjectModel class so it conforms to the NSCopying protocol and implements the copyWithZone: method. And also properly implement the isEqual: and hash methods. Or change the key to be just the idProject property (properly wrapped as an NSNumber).

Related

Access and change values of an NSMutableDictionary from one class to another iOS

I am dealing with NSMutableDictionary in one class, But I want to change it's value in an another class.
Here is the code where it is declared.
#interface MyClass0 : NSObject
{
#public
NSMutableDictionary *valuee;
}
#property (nonatomic, copy) NSMutableDictionary *valuee;
#end
and in the implementation of myClass0 I do
#synthesize valuee;
and I also declare value as
valuee = #{#"name" : #"Aryan"};
Now I want to access and change the value of this dictionary in an another class.
Use #property (nonatomic, strong) NSMutableDictionary *valuee;
Now assign the value as
self.valuee = [[NSMutableDictionary alloc] init];
You can do this in the init method of your MyClass0.
Now you can access the value from another class like
MyClass0 *myClassInstance = [[MyClass0 alloc] init];
NSMutableDictionary *dict = myClassInstance.valuee;
You can write the getter by hand --
- valuee {
return valuee;
}
so the code instance.valuee will give you the original object not the copy.

NSMutableArray removeObject crash

I'm sorry I'm new to iOS development,this day I encountered a strange problem:
when I remove object from custom object , it always return crash:
reason: '-[__NSArrayI removeLastObject]: unrecognized selector sent to instance
the following code:
#interface Base : NSObject
#property (nonatomic, assign) BOOL isFinish;
#property (nonatomic, strong) NSString *title;
#property (nonatomic, strong) NSString *subTitle;
#property (nonatomic, strong) NSString *tagURL;
#property (nonatomic, assign) NSInteger taskScore;
#property (nonatomic, assign) BOOL inProgress;
#property (nonatomic, assign) NSInteger nowTime;
#property (nonatomic, assign) NSInteger totalTime;
#end
then I use on another class:
#property (nonatomic, strong) NSMutableArray *arr1;
#property (nonatomic, copy) NSMutableArray *arr2;
_arr1 = [[NSMutableArray alloc] init];
for (int i = 0; i < 10; i++) {
Base *b = [[Base alloc] init];
b.title = [[NSString alloc] initWithFormat:#"%d", i];
[_arr1 addObject:b];
}
self.arr2 = [_arr1 copy];// 001, I tried copy or mutable copy
[_arr2 removeLastObject]; //it always crash in here!!
So I look through some reference,some told me must conform nscopying or nsmutablecopying protocol
So I add some method in the Base class #implementation
- (id)copyWithZone:(struct _NSZone *)zone
{
Base *copy = [[[self class] allocWithZone:zone] init];
if (copy) {
[copy setIsFinish:[self isFinished]];
[copy setTitle:[self title]];
[copy setSubTitle:[self subTitle]];
[copy setTagURL:[self tagURL]];
[copy setTaskScore:[self taskScore]];
[copy setInProgress:[self inProgress]];
[copy setNowTime:[self nowTime]];
[copy setTotalTime:[self totalTime]];
}
return copy;
}
But it doesn't work , can some one help me?
First look at the error that you got. It quite clearly states that you sent "removeObject" to an NSArray which doesn't understand it, and not to an NSMutableArray. The logical conclusion is that at this point in time, _arr2 is not a mutable array but an NSArray.
Now as a software developer, you should try to think this through logically. You know the difference between copy and mutableCopy, right? You say you used mutableCopy, but what do you think happens when you set a property that is marked as "copy"? It copies. By calling copy. So you made a mutable copy of your mutable nsarray, and the property setter makes an immutable copy.
I think you need to use mutableCopy instead of copy. Copy will create immutable copy of the array. The removeLastObject is available on mutable version of the Array.

Why can I not initialize this NSArray With Objects?

I have an array containing objects of a custom-made class. However, on initialization the compiler gives me an error - "Lexical or Preprocessor" Expected ':'
interface myClass : NSObject
#property (readwrite, strong) NSString* name;
#property (readwrite, strong) NSString* home;
#property (readwrite, strong) Preference pref; // This is another custom class
-(id) initWithName:(NSString*) name home:(NSString*) home preference:(Preference) preference;
end
#interface MyViewController()
#property (nonatomic, strong) NSArray *rowArray;
#end
#implementation MyViewController
...
...
...
- (void) initializeArray
{
self.rowArray = #{
[[myClass alloc] initWithName:#"Harry" home:#"New York" preference :Acura],
[[myClass alloc] initWithName:#"Win" home:#"Seattle" preference :Toyota];
};
}
Can someone tell me just where I am messing up and why I'm getting this error?
The Objective-C literal for an array is with square brackets,
NSArray *anArray = #[obj1, obj2].
In the code you posted it is trying to make a Dictionary,
NSDictionary *aDict = #{"key1" : obj1, #"key2" : obj2}
so this is why it is saying it expects a :.
The line should read,
self.rowArray = #[
[[myClass alloc] initWithName:#"Harry" home:"New York" preference :Acura],
[[myClass alloc] initWithName:#"Win" home:"Seattle" preference :Toyota];
];
As others have pointed out the there are a few other errors with the code and those city names are not NSString's, but I guess this is just an example snippet.

Custom Object empty after creation

I have a custom object: Vendor that extends NSObject. I am initiating it like so:
NSDictionary *vendorObj = [vendors objectAtIndex:i];
Vendor *vendor = [[Vendor alloc] initWithVendorInfo:vendorObj];
NSLog(#"VendorObj: %#", vendorObj);
NSLog(#"Vendor: %#", vendor);
Here is what the class looks like:
#interface Vendor : NSObject
#property (nonatomic, copy) NSString *name;
#property (nonatomic, copy) NSString *description;
- (id)initWithVendorInfo:(NSDictionary *)vendorDetails;
#end
#implementation Vendor
- (id)initWithVendorInfo:(NSDictionary *)vendorDetails
{
self = [super init];
if(self)
{
_name = [vendorDetails[#"company_name"] copy];
_description = [vendorDetails[#"description"] copy];
}
return self;
}
If I NSLog vendorObj all the details are there. Once I initiate the Vendor object and NSLog it, the log shows:
2013-11-21 22:22:44.769 [48202:a07] Vendor:
I cannot seem to figure out why my object is nothing, no memory address, not even a null. What am I doing wrong here?
The problem is your description property. The NSObject class defines a description method. This method is called when you use a %# format specifier with an object.
Your description property is overriding that method.
Rename your description property to something else.

Initialization of custom object return null [duplicate]

This question already has an answer here:
why is my code outputting *nil description*
(1 answer)
Closed 10 years ago.
Here is my custom class:
ClassA.h
#interface ClassA : NSObject<RKRequestDelegate>{
NSString *uri;
NSString *folderUri;
NSInteger idFolder;
NSString *kind;
bool isMine;
CustomUser *owner;
NSMutableArray *usersAdministrators;
NSMutableArray *usersContributors;
NSMutableArray *usersReaders;
NSString *visibility;
NSString *name;
NSString *description;
NSMutableArray *comments;
}
#property (nonatomic,copy) NSString *uri;
#property (nonatomic,copy) NSString *folderUri;
#property (nonatomic,assign) NSInteger idFolder;
#property (nonatomic,copy) NSString *kind;
#property (nonatomic,assign) bool isMine;
#property (retain) DMIUser *owner;
#property (nonatomic,copy) NSMutableArray *usersAdministrators;
#property (nonatomic,copy) NSMutableArray *usersContributors;
#property (nonatomic,copy) NSMutableArray *usersReaders;
#property (nonatomic,copy) NSString *visibility;
#property (nonatomic,copy) NSString *name;
#property (nonatomic,copy) NSString *description;
#property (nonatomic,copy) NSMutableArray *comments;
#end
ClassA.m
#implementation ClassA
#synthesize uri,folderUri,idFolder,kind,isMine,owner,usersAdministrators,usersContributors,usersReaders,visibility,name,description,comments;
-(NSString*)description {
return #"ClassA";
}
#end
Quite simple. But when i try to create new instance of this, like this:
datas = [NSMutableArray array]; // Tried with [[NSMutableArray alloc] init] => same thing
ClassA *classA = [[ClassA alloc] init];
[datas addObject:classA];
NSLog(#"classA = %#",classA);
NSLog(#"datas = %#",datas);
First NSLog returns "ClassA".
Second NSLog returns "datas = ()"
What's wrong here? I always created class like this and i've never had problem like this.
Thanks!
Ok guyzzz i found the problem. It's my attribute:
NSString *description;
Seems that iOs doesn't love that. It conflict with the -description method in NSObject...
After that, i found a similar question here:
Why can't I use "description" as an attribute name for a Core Data entity?
Cheers
if your want to return some value implement method description in the ClassA
- (NSString *)description {
return #"ClassA";
}
You've got everything you need. Are you sure the variable you're assigning to isn't a weak one? All delegate properties are weak, therefore not retaining the object. My guess is that you're doing something like this
someObject.delegate = [[ClassA alloc] init];
NSLog(#"%#", someObject.delegate);
Because the delegate property is weak it doesn't hold onto the variable.
Edit:
This whole answer assumes you are using ARC. If not, disregard.

Resources