iOS parser alloc breakpoint - ios

.h
#class HtmlParser
#interface ClassName : NSObject <UITableViewDataSource>
{
NSString *img;
HtmlParser *htmlParser;
}
: )
.M
- (NSString*)img
{
if (img!=nil) return img;
if (_description!=nil)
{
// NSString* description = [NSString stringWithString:_description];
htmlParser = [[HtmlParser alloc] loadHtmlByString:(NSString*) _description];
}
return img;
}
I am trying to initialize HtmlParser with the contents of description. "description" is RSS html loaded asynchronously, started in the tableViewController.
I get a breakpoint with or without the NSString* description. '-[HtmlParser loadHtmlbyString:]: unrecognized selector sent to instance 0x75aa9b0'... That's all the debugging I know how to do. Breakpoints are enabled for all exceptions.
-the method in .m is called in the viewController's cellForRowAtIndexPath:
ClassName *object = _objects[indexPath.row];
NSString *i = object.img;
UIImage* iG = [UIImage imageWithData:
[NSData dataWithContentsOfURL:[NSURL URLWithString:i]]];
cell.imageView.image = iG;
Its messy so let me know if further clarification is needed.
.h
#interface HtmlParser: NSObject <NSXMLParserDelegate>
{
ET Cetera
}
- (id) loadHtmlByString:(NSString *)string;

When you call the method in question:
htmlParser = [[HtmlParser alloc] loadHtmlbyString:(NSString*) _description];
It shouldn't have the (NSString *) in there. It should be:
htmlParser = [[HtmlParser alloc] loadHtmlbyString: _description];
But, is loadHtmlbyString an init method? If so, then you should start the name with init, and you should also adhere to the naming conventions by capitalizing all the words in the name (including By).

The 'loadHtmlbyStringmethod is not a method of theHtmlParserclass, it is a method of yourClassName` class.
Don't you get a compiler warning on this line:
htmlParser = [[HtmlParser alloc] loadHtmlbyString:(NSString*) _description];
Look at the .h for the HtmlParser class and see what methods are defined for that class.

Related

Objective C Properties memory issue

i have to show the user details from NSUserDefaults in more than 5 view controllers. So i have created a NSObject subclass, which will load the user details from server when the first view controllers viewDidLoad is called.
Here is my First view controller viewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
// Getting the Current User Details
CurrentUserDetails *userDetails = [[CurrentUserDetails alloc]init];
[userDetails initializeTheCurrentUserData];
//CurrentUserDetails is my NSObject class
}
And
#import <Foundation/Foundation.h>
#interface CurrentUserDetails : NSObject
#property(strong,nonatomic) NSString *memberName;
#property(strong,nonatomic) NSString *designation;
#property(strong,nonatomic) NSString *memberType;
#property(strong,nonatomic) NSString *entreprenuer;
#property(strong,nonatomic) NSDate *expiryDate;
#property(strong,nonatomic) NSData *imageData;
- (void) initializeTheCurrentUserData;
#end
and implementation
#implementation CurrentUserDetails
- (void) initializeTheCurrentUserData{
NSData *data = [[NSUserDefaults standardUserDefaults] valueForKey:#"userDictionary"];
NSDictionary *retrievedDictionary = [NSKeyedUnarchiver unarchiveObjectWithData:data];
self.memberName = [retrievedDictionary valueForKey:#"Name"];
self.designation = [retrievedDictionary valueForKey:#"Designation"];
self.memberType = [[retrievedDictionary valueForKey:#"Member_type"] stringValue];
self.expiryDate = [retrievedDictionary valueForKey:#"Expiry"];
self.kanaraEntreprenuer = [retrievedDictionary valueForKey:#"CityName"];
NSString *imageUrl = [retrievedDictionary valueForKey:#"Member_image"];
self.imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#%#",[GlobalVariables getBaseURLForMemberImage],imageUrl]]];
}
And when iam trying to take the details from other class like this..
CurrentUserDetails *userDetails = [[CurrentUserDetails alloc]init];
memberName = userDetails.memberName;
designation = userDetails.designation;
memberType = userDetails.memberType;
dateFromServer = userDetails.expiryDate;
entreprenuer = userDetails.entreprenuer;
imageDataFromServer = userDetails.imageData;
I am getting nil values.
But if call initializeTheCurrentUserData method each time, i am getting the exact values. I though once a property is assigned with a value , we can use the property for entire program. I'm getting confusion.. Can anyone please tell me about this????. Do i need to call initializeTheCurrentUserData everytime when i want to use the values?
Once you set a property of an instance, that property remains for that instance. You, however, are creating new instances with [[CurrentUserDetails alloc] init]. Each new instance will be initialized with default values (nil for NSString).
Call -initializeTheCurrentUserData in -init so each instance will be initialized with the values from user defaults.
#implementation CurrentUserDetails
- (instancetype)init {
self = [super init];
if (self != nil) {
[self initializeTheCurrentUserData];
}
return self;
}
- (void)initializeTheCurrentUserData {
…
}

NSString : leak when assigning value to a property

Assuming we don't use ARC.
Suppose we have a very simple class in which we declare 2 NSString properties, like this :
#interface Foo : UIView {}
-(id)initWithArguments:(NSString*)mess title:(NSString*)tit;
#property(nonatomic, retain) NSString *message;
#property(nonatomic, retain) NSString *title;
#end
and in implementation :
#implementation Foo
#synthesize message, title;
-(id)initWithArguments:(NSString*)mess title:(NSString*)tit{
if((self = [super init])){
message = mess; // (1)
self.title = tit; // (2)
(...)
}
return self;
}
-(void)dealloc{
message = nil;
title = nil;
[super dealloc];
}
#end
Now if I call a method from another class, in which I create 2 NSString and an instance of Foo , like this :
-(void)someMethod{
NSString *string1 = [NSString stringWithFormat:#"some text with %d things", 5];
NSString *string2 = [NSString stringWithFormat:#"other text with %d things", 5];
Foo *foo = [[Foo alloc] initWithArguments:string1 title:string2];
}
The whole code works fine and doesn't crash, but, if I profile it with instruments,
it doesn't cause a leak when calling (1)("message = mess;")
it cause a leak when calling (2)("self.title = tit;")
It's very confusing, because stringWithFormat is an autoreleased object, isn't it ?
So, how an autoreleased object can cause a leak when assigning to a property ???
I read somewhere that it's almost always better to use the "self.text = value;" form instead of the "text = value;" form, because the second one may cause a leak.
Actually, in this code it's the contrary.
And... If I use a constant NSString like #"some text", instead of the values returned by [NSString stringWithFormat], there is no leak, of course.
Any idea ?
You have forgotten to invoke the (compiler-generated) setter methods in a few cases:
self.message = mess; // in init method
self.message = nil; // in dealloc method
self.title = nil; // ditto
It's crucial that you use the setter/getter methods in non-ARC code.

How to call category method in another class

I have category class have method to encode the url. So how to use this method in another class. Thank in advance
NSString+EncodeURL.h
#import <Foundation/Foundation.h>
#interface NSString (EncodeURL)
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding;
#end
NSString+EncodeURL.m
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {
return (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)self,
NULL,
(CFStringRef)#"!*'\"();:#&=+$,/?%#[]% ", CFStringConvertNSStringEncodingToEncoding(encoding)));
}
and in another class. How to convert urlString to a string using urlEncodeUsingEncoding in Category class
#import "WatchVideosViewController.h"
#import "CustomCell.h"
#import "ImageRequest.h"
#import "Constant.h"
#import "ImageCache.h"
#import "NSString+EncodeURL.h"
#interface WatchVideosViewController ()
#property (weak, nonatomic) IBOutlet UIImageView *imageBackground;
#end
#implementation WatchVideosViewController
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString * CellIndentifier = kCellName;
CustomCell *cell = (CustomCell*)[collectionView dequeueReusableCellWithReuseIdentifier:CellIndentifier forIndexPath:indexPath];
NSDictionary *dictVideo = [self.videoList objectAtIndex:indexPath.row];
//start indicator
[cell.indicator startAnimating];
//set title
NSString *titleVideo = [dictVideo objectForKey:kTitleKey];
[cell.myLabel setText:titleVideo];
// set image url
NSString *urlVideo = [dictVideo objectForKey:kUrlKey];
NSURL *url = [NSURL URLWithString:urlVideo];
NSString *urlString = [url absoluteString];
NSString *encodeURL=[urlString ]
//encode url
In the file you want to make use of -urlEncodeUsingEncoding:, simply add:
#import "NSString+EncodeURL.h"
All NSString instances in that file will respond to -urlEncodeUsingEncoding:.
import "NSString+EncodeURL.h"
in the class u want to run NSString+EncodeURL.h--this class's method
Now u got to select where u got to run the method of (NSString+EncodeURL.h) this class.
suppose u want it to run in viewDidLoad,so
Create an instance of the class in the method.
NSString+EncodeURL *myInstance;
[myInstance methodname];
In the class where you want to use the category method, just simply import the category header as below.
#import "NSString+EncodeURL.h"
Then, use the category method as below
NSString *encodeURL = [urlString urlEncodeUsingEncoding:urlString];
Thats it, Simple, Bingo!
Example with NSStringEncoding is NSUTF8StringEncoding. You can convert urlString to encodeURL by call:
NSString *encodeURL=[urlString urlEncodeUsingEncoding:NSUTF8StringEncoding];
function CFStringConvertNSStringEncodingToEncoding() will convert NSUTF8StringEncoding to kCFStringEncodingUTF8
As in your code if you want to encode the url just write
NSString *encodeURL=[urlString urlEncodeUsingEncoding:NSUTF8StringEncoding]; //whataver encoding you want just pass
If code completion is not showing than there may be problem with indexing just terminae xcode reopen clean and build.It should work.

Calling method from another file [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I am a beginner in Objective-C. I would like to call the method two in file you.m from file me.m. Could you please teach me with simple example showing below to understand. Thank you!
you.h
#import <Foundation/Foundation.h>
#interface you : NSObject {
}
- (NSString *)one;
- (NSString *)two;
#end
you.m
#import "you.m"
#implementation you
- (NSString *)one {
NSString *a = #"this is a test.";
return a;
}
-(NSString *)two {
NSString *b = [self one];
return b;
}
#end
me.h
#import <Foundation/Foundation.h>
#interface me : NSObject {
}
#end
me.m
#import "you.h"
#import "me.h"
#implementation me
-(void)awakeFromNib{
//NSString *obj = [[[NSString alloc] init] autorelease];
//NSString *str = [obj two]; // dont work
//NSString *str = [self two]; // dont work
// I'd like to call method *two* from here.
NSLog(#"%#", str);
}
#end
In me class, create an instance of you.
you *objectYou=[you new];
As two returns a string, you need to store it :
NSString *string=[objectYou two];
In your code:
-(void)awakeFromNib{
you *objectYou=[you new];
NSString *str = [objectYou two];
NSLog(#"%#", str);
}
NOTE: Follow naming conventions. Class names must start with Capital letter like Me, You.
EDIT:
As you are learning, I would like to add one more thing, as you are calling one from two. If one is not meant to be called outside you class. You can define it in .m and remove the declaration from .h.
Simple, create an instance of You class in Me class and call that member function. Like so -
you *youInstance = [[you alloc] init];
NSString *retStr = [youInstance two];
Btw, its a good practice to CamelCase class names.
Also note this -
#interface you
- (NSString *) twoInstanceMethod;
+ (NSString *) twoClassMethod;
#end
NSString *retStr = [you twoClassMethod]; // This is ok
NSString *retStr = [you twoInstanceMethod]; // this doenst't work, you need an instance:
//so we create instance.
you *youInstance = [[you alloc] init];
NSString *retStr = [youInstance two];
Hope this clears some concepts...

No visible #interface for 'class-name' declares the selector 'method-name'

I'm writing a method as below in my View Controller:
- (IBAction)expressionEvaluation:(UIButton *)sender {
NSDictionary *testValues = [NSDictionary dictionaryWithObjectsAndKeys:#"x", 2, #"y", 3, #"z", 4, nil];
//the below line gives the error
double result = [self.brain evaluateExpression:self.brain.expression usingVariableValues:testValues];
NSString *resultString = [NSString stringWithFormat:#"%g", result];
self.display.text = resultString;
}
And in my 'brain' class I have declared the not-yet-finished method:
#import <Foundation/Foundation.h>
#interface CalculatorBrain : NSObject
- (void) pushOperand:(double)operand;
- (void) setVariableAsOperand:(NSString *)variableName;
- (void) performWaitingOperation;
- (double) performOperation:(NSString *)operation;
#property (readonly) id expression;
+ (double)evaluateExpression: (id)anExpression
usingVariableValues: (NSDictionary *)variables; //declared here
#end
...in the .h, and in the .m:
+ (double) evaluateExpression:(id)anExpression usingVariableValues:(NSDictionary *)variables {
double result = 0;
int count = [anExpression count];
for (int i = 0; i < count; i++) {
}
return result;
}
Why am I getting this "No visible #interface for 'CalculatorBrain' declares the selector 'evaluateExpression:usingVariableValues'"error? I'm new to objective-c, but I imagine this means it's not seeing my declaration. I'm not sure if it's a syntax/formatting issue, though, because I'm new to the language.
notice that you declare evaluateExpression:usingVariableValues: as class method
+ (double)evaluateExpression: (id)anExpression // + means class method
usingVariableValues: (NSDictionary *)variables; //declared here
and use it like instance method
// assuming self.brain is an instance of CalculatorBrain
[self.brain evaluateExpression:self.brain.expression usingVariableValues:testValues];
so either change the method to
- (double)evaluateExpression: (id)anExpression // - means instance method
usingVariableValues: (NSDictionary *)variables; //declared here
or call it like this
[CalculatorBrain evaluateExpression:self.brain.expression usingVariableValues:testValues];
the "+" sign means class method. You can access it through your class name not an instance of it.
like
[MyClass methodName];
a "-" sign means instance method. You can access it through an instance of your class (after having allocated-inited it.
like
MyClass *myInstance = [[MyClass alloc] init];
[myInstance methodName];
MOXY is right.
+ (double)evaluateExpression: (id)anExpression;
is a class method, and is sent to the class. You typically use class methods for things like constructing new objects:
+ (NSString*) stringWithString: (NSString*) s;
What you want is an instance method:
- (double) evaluateExpression: (id) anExpression;
which you would send to an instance on your object.

Resources