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.
Related
I use JSONModel to hold my app datasource, and use -(id)initWithArray:(NSArray *)array modelClass:(Class)cls generated an JSONModelArray, now I want to do some search stuff like enumerateObjectsUsingBlock: method does. But I found that JSONModelArray is not inherited from NSArray.
So, how can I do this?
Try use BWJSONMatcher to convert json string to a NSArray.
For example, your json string seems like :
[{"name":"Arron","age":20,"grade":2},{"name":"Burrows","age":21,"grade":2}]
All you have to do is declare your own data model:
#interface Student : NSObject
#property (nonatomic, strong) NSString *name;
#property (nonatomic, assign) NSInteger age;
#property (nonatomic, assign) NSInteger grade;
#end
BWJSONMatcher will help you convert it to a NSArray in a very neat way:
NSArray *students = [BWJSONMatcher matchJSON:jsonString withClass:[Student class]];
Heyo Guys
So I am more or less new to Objective C and got to a problem which I seem unable to solve.
I created a class called "Students" which all have a name surname etc. All those Students are put into a NSMutableArray (before they get created from JSON , that seems to work without a problem though). Then all the names of the students are put into a ListView. Afterwards when a name is clicked (segue passes the object), one should see the details of said student (i.e. his full name, his id, his street).
The problem is that all the string values of the student object seem to get lost.
I checked that all the student object work just fine. I think the problem lies at the #property in my student class.
Any comments and suggestions are appreciated
This is an excerpt of student.h As said only the string values get lost, the int (here the plz value) remains correct
#property (nonatomic, weak)NSString *lastname;
#property (nonatomic, weak)NSString *surname;
#property (nonatomic, weak)NSString *street;
#property (nonatomic, assign)int plz;
EDIT:
Here is where i parse my json.
for (NSDictionary *dic in jsonArray){
NSNumber *identity = [dic valueForKey:#"id"] ;
NSString *firstName = (NSString*) [dic valueForKey:#"first_name"];
NSString *lastName = (NSString*) [dic valueForKey:#"last_name"];
NSString *street = (NSString*) [dic valueForKey:#"street"];
NSNumber *plz = [dic valueForKey:#"plz"] ;
NSString *birth = (NSString*) [dic valueForKey:#"date_of_birth"];
NSArray *bills = dic[#"bills"];
NSArray *hours = dic[#"hours"];
NSLog(#"First %#",firstName);
Student *student = [[Student alloc]initWithLastName:lastName withSurname:firstName withStreet:street withPLZ:plz withOrt:#"Uitikon" withBirthDate:birth withOccupation:#"Schüler"];
[ApprenticeList addObject:student];
}
EDIT 2 :
I found out that the string values get lost even before the segue. All these objects are created in
ViewDidLoad
But in
prepareforsegue
all the values are allready null (except for the int) .So the only place where the student objects work is in
ViewdidLoad
#property (nonatomic, weak)NSString *lastname;
#property (nonatomic, weak)NSString *surname;
#property (nonatomic, weak)NSString *street;
change to
#property (nonatomic, strong)NSString *lastname;
#property (nonatomic, strong)NSString *surname;
#property (nonatomic, strong)NSString *street;
You can also use 'copy'. It will cause the setter for that property to create a copy of the object, otherwise it is identical to strong.
I have this simple model class that represent rss article called RSSEntry.
Now I want to start working wit core data with this model class, but I didn't create the project with the 'use core data' checkbox checked.
this is the class:
#import <Foundation/Foundation.h>
#interface FRSSEntry : NSObject{
NSString *_blogTitle;
NSString *_articleTitle;
NSString *_articleUrl;
NSDate *_articleDate;
NSString *_articleImageUrl;
NSString *_content;
}
#property (copy) NSString *blogTitle;
#property (copy) NSString *articleTitle;
#property (copy) NSString *articleUrl;
#property (copy) NSDate *articleDate;
#property (copy) NSString *articleImageUrl;
#property (copy) NSString *content;
- (id)initWithBlogTitle:(NSString*)blogTitle articleTitle:(NSString*)articleTitle articleUrl:(NSString*)articleUrl articleDate:(NSDate*)articleDate articleImageUrl:(NSString *)imageUrl andContent:(NSString *)content;
#end
the implementations is:
#import "FRSSEntry.h"
#implementation FRSSEntry
#synthesize blogTitle = _blogTitle;
#synthesize articleTitle = _articleTitle;
#synthesize articleUrl = _articleUrl;
#synthesize articleDate = _articleDate;
#synthesize articleImageUrl = _articleImageUrl;
#synthesize content = _content;
- (id)initWithBlogTitle:(NSString*)blogTitle articleTitle:(NSString*)articleTitle articleUrl:(NSString*)articleUrl articleDate:(NSDate*)articleDate articleImageUrl:(NSString *)imageUrl andContent:(NSString *)content
{
if ((self = [super init])) {
_blogTitle = [blogTitle copy];
_articleTitle = [articleTitle copy];
_articleUrl = [articleUrl copy];
_articleDate = [articleDate copy];
_articleImageUrl = [imageUrl copy];
_content = [content copy];
}
return self;
}
#end
very simple. Now how do I convert it so I can use it as a core data entity?
So to transform your model class into an NSManagedObject subclass you have to remove the instance variable declarations. Then replace all your #synthesize statements with #dynamic. This tells the compiler that CoreData will provide the implementation for those properties so it can do it's magic there. The custom initializer you have then also needs to be removed because NSManagedObject objects are initialized in a different way.
The code would look something like
#import <Foundation/Foundation.h>
#interface FRSSEntry : NSManagedObject
#property (copy) NSString *blogTitle;
#property (copy) NSString *articleTitle;
#property (copy) NSString *articleUrl;
#property (copy) NSDate *articleDate;
#property (copy) NSString *articleImageUrl;
#property (copy) NSString *content;
#end
-
#import "FRSSEntry.h"
#implementation FRSSEntry
#dynamic blogTitle;
#dynamic articleTitle;
#dynamic articleUrl;
#dynamic articleDate;
#dynamic articleImageUrl;
#dynamic content;
#end
You usually initialize them with something like
// Get the entity description
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"FRSSEntry" inManagedObjectContext:context];
// Insert a new YourModelObject into the context
ReceivedMessage *newMessage = [[FRSSEntry alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:context];
You could have a custom initializer but you would have to call [super initWithEntity:entityDescription insertIntoManagedObjectContext:context]. The initializer would get really long with all this parameters so I suggest you just set each property once you have the object initialized.
Judging from your response, you have just begun CoreData integration. Creating an NSManagedObject subclass is just a tip of the iceberg when working with core data. CoreData is a big an complex framework so I suggest you start by reading https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/cdProgrammingGuide.html. Stack Overflow is also full of questions and great answers on this topic.
Another thing I suggest you look into is MagicalRecord. It's a great library that makes some of the tedious tasks very simple: https://github.com/magicalpanda/MagicalRecord
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.
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.