.h file
UIImage *ownImg;
#property (nonatomic, retain) UIImage *ownImg;
.m file
In viewWillAppear method:
UIImage *myImage2 = [UIImage imageNamed:#"thumbnail.png"];
self.ownImg = myImage2;
That is a leak in ownImg, anyone know why it leaking?
BTW, what is the different of using self.ownImg and without the self.
Thanks.
Calling
ownImg = myImage2;
is just an assignment that merely sets the pointers. But calling
self.ownImg = myImage;
will call a #synthesized setter that contains a retain. (I assume you have the #synthesize() for the ownImg.)
Because you're using a setter method that retains you'll have to release it somewhere. Try placing that in the override for the unload method, or if a non-nib class place it in the dealloc.
Related
Why is blackview always null?
#property (strong, nonatomic) UIView *blackView;
[_blackView setFrame:self.view.bounds];
[_blackView setBackgroundColor:[UIColor colorWithWhite:0 alpha:0.8]];
[self.view addSubview:_blackView];
NSLog(#"%#", _blackView); // i get null
I was instantiating it using alloc init before but i need to access this view between methods so i am using it as a property
Try using self.blackview and initialize
self.blackview = [[UIView alloc] initWithFrame:self.view.frame];
Before you do anything to the object(UIView). You must allcate momery for it, and do some initializations. Use alloc and init method. Like:
UIView *blackView = [[UIView alloc] initWithFrame:CGrectMake( , , , )];
I must say, this is something that even the beginners should know.
After you have created a property. Make sure you have synthesized it.
#synthesize blackView;
And then make sure you alloc some memory to it atleast, use
self.blackView = [[UIView alloc]init];
And then you can perform, any function on it, that you want.
#property (strong, nonatomic) UIView *blackView;
Here you have made the decalaration. But that does not mean that you have allocated any memory to it.
In your implementation file you need to allocate memory to it and initialise it as well.
If you are using XCode version 6 and above you dont need to synthesize your property because that is done by Xcode itself.
Otherwise you need to syntesize your property.
#synthesize blackView;
self.blackView = [UIView alloc]initWithFrame:self.view.bounds];
Also if you have a nib file, and there you have alraedy added a UiView and you want it to be your blackView then you have to make an IBoutlet Connection from your nib file to your .h file. in this case you dont need to initialise or allocate memory to your UIView object. That is done by iOS SDk itself.
I have few questions to ask about the following class
#import <Cocoa/Cocoa.h>
#interface SomeObject {
NSString *title;
}
#property (retain) NSString *title;
#end
implementation SomeObject
#synthesize title;
-(id)init {
if (self=[super init])
{
self.title=[NSString stringWithFormat:#"allyouneed"];
}
return self;
}
-(void)testMethod{
self.title=[[NSString alloc] init] ;
}
-(void)dealloc {
self.title=nil;
[super dealloc];
}
In the .h file do we need to declare the title and sub when we add the property. is it not enough to add the #property (retain) NSString *title; line.
2.Do i need to autorelease both assignment to title in the init and testMethod. if So why?
Can some one explain these things to me.
1-
You don't need to declare the iVar in the header. You might also use
#synthesize myVar = _myVar;
if you want to go for a different iVar name
2-
Declaring a property "retain" means that every time you assign the property with a new object, it automatically releases the previous object and retain the new one.
Therefore, if you use a convenience method like stringwithFormat, the property will retain that object for you.
If you want to use alloc-init, for me the best way to do is:
NSString *str = [NSString alloc] init];
self.title = str;
[str release];
Besides, it is right to assign nil to the property in the dealloc because the property will release the object it has, and it calls retain on nil which doesn't do anything
1.No need to declare title in .h, declaring property is enough.
2.when you are using self.title in init, you do not have to autorelease it.But when you initialize it in testMethod, you need to autorelease it because you have declare the property as retain.And do not forget to release title in dealloc.
you don't need to add as it is done automatically (Since Xcode 4 I guess).
in init- you don't as it already returns an autoreleased object..
where as in testMethod you need to since you are allocating it..
you always have to release any object which you create using alloc , copy or new .... AMEN.. :)
Be aware it is not considered a good practice to use accessor methods in initializer methods and dealloc method. Do check out this answer: Why shouldn't I use Objective C 2.0 accessors in init/dealloc?
Also in Apple's memory management guide: https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html
I have a leakage in my connectionDidFinishLoading class how can fix this?
#property (nonatomic,retain) NSMutableData *responseXMLData;
#property (nonatomic,copy) NSMutableData *lastLoadedResponseXMLData;
-(void)dealloc {
[responseXMLData release] ;
responseXMLData=nil;
[lastLoadedResponseXMLData release];
lastLoadedResponseXMLData=nil;
[super dealloc];
}
#property (nonatomic,copy) NSMutableData *lastLoadedResponseXMLData;
Since you are working with a mutable object that you are going to be setting and changing, you should use RETAIN:
#property (nonatomic,retain) NSMutableData *lastLoadedResponseXMLData;
retain - "Specifies that retain should be invoked on the object upon assignment. ... The previous value is sent a release message." So you can imagine assigning an NSString instance (which is an object and which you probably want to retain).
copy - "Specifies that a copy of the object should be used for assignment. ... The previous value is sent a release message." Basically same as retain, but sending -copy rather than -retain.
Here is some good reading on the various get/set methods you can instruct #property/#synthesize to create for you: http://cocoawithlove.com/2010/06/assign-retain-copy-pitfalls-in-obj-c.html
you did not tell us where you are creating the object for responseXMLData? where ever you are initializing that object should release that
self.responseXMLData = [[NSMutuableData alloc]init]autorelease];
and in your dealloc method you could have just say
-(void)dealloc {
self.responseXMLData = nil; //which is equivalent to [responseXMLData release]; responseXMLData=nil;
}
and
Just a thought, in your:
self.lastLoadedResponseXMLData = nil;
self.lastLoadedResponseXMLData = self.responseXMLData;
Before one release happens at dealloc, could there be a possible where your just set to nil and copy next responseXMLData to lastLoadedResponseXMLData without releasing any previous copies?
This makes no sense to me. Maybe someone here can explain why this happens.
I've got an NSMutableString that I alloc at the top of my iPhone app, then append to later in the process. It results in a SIGABRT, which doesn't add up to me. Here's the code:
Header File (simplified):
#interface MyAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
NSMutableString *locationErrorMessage;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, copy) NSMutableString *locationErrorMessage;
#end
And the relevant parts of the Main:
#implementation MyAppDelegate
#synthesize window;
#synthesize locationErrorMessage;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
self.locationErrorMessage = [[NSMutableString alloc] init];
}
- (void)anotherFunction {
[self.locationErrorMessage appendString: #"Blah Blah Blah"];
}
This all seems simple enough. What am I missing?
I would call this a bug in how property setters are generated, but the answer is pretty simple:
You declared the property as (nonatomic, copy). This means that whenever the locationErrorMessage property is set, it's going to invoke copy on the new value and use that copy as the property value.
Unfortunately, invoking copy on an NSMutableString does not result in an NSMutableString, it results in an NSString (which cannot be mutated using something like appendString:).
So the simple fix would be to change the property declaration from copy to retain.
(I would say that the bug would be: If you declare a property for a mutable object as copy, then the copy setter should actually use mutableCopy and not copy) => rdar://8416047
Your property is copying the passed in string. A copy always is immutable, so you’re trying to send appendString: to an immutable NSString. Declare your property as retain and it will work or write a custom setter that copies the string using mutableCopy.
You also have a memory leak, you should use [NSMutableString string] instead of the alloc-init sequence.
Btw, you have a leak there,
self.locationErrorMessage = [[NSMutableString alloc] init];
you're copying the value, but you never release the actual first allocated NSMutableString.
When do you have to use #property and #synthesize in the iPhone SDK? And why use #property and #synthesize?
I was studying property, but I can't get a correct idea. What would some examples for illustrating this be?
#property : you used it when you want to:
You can use some of the really useful generated code like nonatomic, atmoic, retain without writing any lines of code. You also have getter and setter methods. To use this, you have 2 other ways: #synthesize or #dynamic: #synthesize, compiler will generate the getter and setter automatically for you, #dynamic: you have to write them yourself.
#property is really good for memory management, for example: retain.
How can you do retain without #property?
if (_variable != object) {
[_variable release];
_variable = nil;
_variable = [object retain];
}
How can you use it with #property?
self.variable = object;
When you are calling the above line, you actually call the setter like [self setVariable:object] and then the generated setter will do its job
#property (along with #synthesize) automatically generates set and/or get code. So the following code:
self.prop = #"some string";
is equivalent to
[self setProp: #"some string"];
Note also,
self.prop = #"some string";
is different from
prop = #"some string";
The latter sets the variable directly, whereas the former calls the method getProp to set the variable prop.