I have this case where I just Call the init of Class I made this class is subclass of NSObject.
- (instancetype)initArray
{
self = [super init];
if (self) {
//Do Some Logic
}
return self;
}
This is my Call from the App Delegate
CategoryLoader *categoryLoader = [[CategoryLoader alloc]initArray];
Whats driving me crazy is that:
Although it returns nil it goes into the if condition
It doesn't return nil on other computer with other Xcode
Please note that both Xcode's are 6.3
Solutions i tried:
Cleaned Cache of Xcode
Deleted the class and created a new one
Reinstalled Xcode
Here is a Screenshot of whats happening:
Any suggestions why could it be returning nil from NSObject and what can i do next ?
Thank you
NSObject’s implementation of init should never return nil. This is documented in the NSObject Class Reference: although slightly confusing, the key part is
The init method defined in the NSObject class does no initialization; it simply returns self.
If you are observing it retuning nil, either something is not setup how you expect (perhaps the class isn’t a direct subclass of NSObject), or you are somehow interpreting the results incorrectly, or there is something wrong at another level. The fact that you observe different results on different machines suggests it might be at another level, like Xcode, the operating system, or the hardware. I can’t help much there; try rebooting.
Also, your method ought to be named init not initArray. This is not a requirement but a very strong convention. You can read about Object Initialization in Apple’s Concepts in Objective-C Programming
Ok. That was the problem:
The the scheme was on Release Mode. In this case the watch window displays nil in most of the objects. When I printed the value of self on NSLog it printed its value. The only difference between me and the other Xcode was the scheme.
So the solution is to edit the scheme of the project to be debug.
Thank you for your support
Related
During iOS development I'm using a lot of classes which come from proprietary code which I have no access to. I want to run custom code that should run when this class is instantiated into an object, but I don't know how to, as I can't really override their init without knowing what parameters said init takes.
For example I am working on a SceneDelegate which subclasses UIResponder and UIWindowSceneDelegate and I want to have a property which should get initialized when the class is first instantiated, but I don't know how to.
At the moment I am just defaulting to defining the property as optional, initialize it in the method that will first use it, and write a whole bunch of code all around this class to handle the fact that it is unnecessarily optional.
Is there a better way?
Thanks!
You may try to make a class extension with your own init()?
extension SceneDelegate {
init(someParam: ...) {
....
}
}
I have an issue that I've figured out how to fix but I want to understand why it doesn't work -- because it makes no sense to me. Here's a minimal example that demonstrates my issue:
import XCTest
import CoreLocation
class ExampleTests: XCTestCase {
var okay: ext!
// this test works fine
func testOkay(){
okay = ext()
XCTAssertNotNil(okay)
}
// this test crashes with EXC_BAD_ACCESS(code=1, address=0x10)
func testNotOkay(){
let notOkay: ext
notOkay = ext()
XCTAssertNotNil(notOkay)
}
}
extension ExampleTests {
class ext : CLPlacemark{
}
}
I'm following a book to develop a simple TodoList application that uses CoreLocation to geocode addresses. As part of testing, I had to create a mock CLPlacemark object to test the geocoding functionality.
In the book, I was told I had to declare a variable for this mock as a property of the Test class because otherwise "the test would crash since the place mark is accessed outside of its definition scope."
This can be seen in the example above. testOkay() works fine because okay was declared as a class property. testNotOkay() crashes with an EXC_BAD_ACCESS error, because I've tried to instantiate a new instance of ext within the function.
Now, if I do not extend CLPlacemark, the problem goes away -- i.e. I can declare variables of type ext in a function or as a property of the class with no issues.
What is going on here? I see no reason why the second example should crash while the first one works. In my actual code, it seems frivolous to declare my mock placemark instances as class properties when they're only used in one or two functions. There must be something I don't understand about Swift that is causing this problem.
Thanks!!
I recently run into this issue when testing feature which required providing predefined CLPlacemark instances as an input. After some research I found that someone had similar problem with CLBeacon class.
EXC_BAD_ACCESS when setting a CLBeacon to nil
Placemark objects are typically generated by a CLGeocoder object, although you can also create them explicitly yourself.
Despite Apple documentation saying that you can create CLPlacemark instances by yourself. This class is not a nice guy when it comes to subclassing. It depends on a private class called CLPlacemarkInternal which is nil when you create an instance. On the image below you can see how this object looks in debugger. The _internal ivar has value of 0x0 which is nil.
Crash with EXC_BAD_ACCESS message occurs when the object you instantiated gets deallocated. Regardless whether you go out of scope or assign another object (or nil) to the variable. Why is it happening? This is a question to Apple developers. But below you can find some workarounds other people implemented.
http://szulctomasz.com/2015/07/01/ios-unit-testing-in-swift-and-clplacemark-mocking.html
Extending CLPlacemark results in EXC BAD ACCESS
I have also experienced the exact same issue.
I resorted to subclassing MKPlacemark instead.
This finally allowed me to set the desired mock properties I needed to get my test to past
I try to dynamically call certain viewController/Feature depends on his Name.NSClassFromString
(that kind of idea was suggested by Facebook).
For Instance from my server I can define in IOS app which feature or viewController should be used.(or On/Off them)
I searched all over Stack but still cant find an elegant way to implement what I want
Class myclass = NSClassFromString(className);
id obj = [[myclass alloc] init];
will work.
But I would like to call my custom init.
Class myclass = NSClassFromString(className);
id obj = [[myclass alloc] initWithCostumInitializer:userInfo];
I cant find a proper way to do it. Of course every time I receive an error because initWithCostumInitializer is not recognised.So I need to make the decision in run time.I believe I missing something.
Tnx a lot.
First off, you shouldn't get a compile-time error about an unknown method if the headers for the possible classe(s) are imported into the .m file where this code is running. Because of exactly this sort of dynamism, ObjC should let you get away with calling fairly arbitrary methods on objects of type id.
But that's just a bandaid solution. Really, if you know that that custom initializer method is present, then it's not an arbitrary class, right? You have some idea what kind of object it is, or at least what kind of base class it derives from, otherwise you wouldn't know to call that method. So you could always:
id customObj = [((BaseViewController *)[myclass alloc]) initWithCustumInitializer:userInfo];
If your error is a runtime error about the receiver missing that selector, then you have a real problem, which is: why are you calling a named method on an object that might not be the kind of object that has that method? If that's what's happening, you'll need to look at the class first to figure out what kind of thing you're actually about to create, and then behave appropriately for the init.
I'm starting to make use of static code analysis to find memory management problems in my code. I've found it very useful, but there are a couple of bits of code I've written that I'm sure aren't causing memory leaks (instruments doesn't report any) but are being reported by the analyser. I think it's a question of me writing the code in a non-friendly manner. Here's an example
for (glyphUnit *ellipsisDot in ellipsisArray) {
CGPathRef newDot = CGPathCreateCopyByTransformingPath(ellipsisDot.glyphPath, &ellipsisTransform);
CGPathRelease(ellipsisDot.glyphPath); // Incorrect decrement of the reference count of an object that is not owned at this point by the caller
ellipsisDot.glyphPath = newDot;
}
where glyphUnit is a simple custom class that has a GCPathRef as a property, which the custom class releases in its dealloc method. So in this loop I'm transforming the path and storing it in anewDot then releasing the original glyphPath so I can assign the newly created one to it. I can see how this is getting the code analyser confused, with it giving a message I'm decrementing an object I don't own. Is there another way swap in the new path without confusing it?
It should be,
for (glyphUnit *ellipsisDot in ellipsisArray) {
CGPathRef newDot = CGPathCreateCopyByTransformingPath(ellipsisDot.glyphPath, &ellipsisTransform);
ellipsisDot.glyphPath = newDot;
CGPathRelease(newDot);
}
You are creating newDot by doing CG CreateCopy operation and you need to do release on that variable. So the analyser is warning that you dont own ellipsisDot.glyphPath param to release it. You are trying to release the wrong param here. When you put that release statement in the second line as in question, ellipsisDot.glyphPath and newDot are pointing to two separate instances. Only on the third line, you were assigning newDot to ellipsisDot.glyphPath.
It turns out that I forgot about defining setters in my custom glyphUnit class. Being in the ARC world for objects and used to synthesizing my methods I had forgotten the need to manage my retain counts for core foundation references. I had been releasing glyphPath in my dealloc, but was not using a setter method. As #Sven suspected, I was simply using a synthesized assign and making up for my lack of setter method by doing some less than intuitive releases in my code snippet above. I've now added a setter method as below to glyphUnit
- (void)setGlyphPath:(CGPathRef)newPath
{
if (_glyphPath != newPath)
{
CGPathRelease(_glyphPath);
_glyphPath = CGPathRetain(newPath);
}
}
After adding this, I now had the necessary retain in place to change my code snippet to the one #ACB described and my code ran nicely (without it, it obviously caused an EXC_BAD_ACCESS).
Kudos to #Sven for inferring my mistake and setting me in the right direction... no pun intended.
I was wondering how you would release a singleton
+ (DSActivityView *)activityViewForView:(UIView *)addToView withLabel:(NSString *)labelText width:(NSUInteger)labelWidth;
{
// Not autoreleased, as it is basically a singleton:
return [[self alloc] initForView:addToView withLabel:labelText width:labelWidth];
}
When analysing this using the analyse tool i get the following error :
Potential leak of object on line 90. which is the line that returns.
I have tried autorelease that solves the error message problem but im not convinced its the right solution since i read that autoreleasing singletons is not good. Would someone be able to assist me in identifying how best to release this object?
Thanks
The reason why the analyzer gives you the warning is, basically, the method name:
+ (DSActivityView *)activityViewForView:(UIView *)addToView withLabel:(NSString *)labelText width:(NSUInteger)labelWidth;
according to Objective-C conventions, all method names starting with "create"/"new"/... return a retained object; your method falls under the category of convenience constructors, which are expected to return autoreleased objects, hence the warning.
On the other hand, you say this is a singleton, but in fact it is not. So, you could possibly end up calling this method more than once and thus have an actual leak. A basic way to make your method safer (and more singleton-like) is:
+ (DSActivityView *)activityViewForView:(UIView *)addToView withLabel:(NSString *)labelText width:(NSUInteger)labelWidth;
{
static DSActivityView* gDSActivityViewSingleton = nil;
if (!gDSActivityViewSingleton)
gDSActivityViewSingleton = [[self alloc] initForView:addToView withLabel:labelText width:labelWidth];
return gDSActivityViewSingleton;
}
This would both make the analyzer relax and give you more safety in front of the possibility of misuse of the method.
Use autorelease. There's no reason not to. Basically ownership of the object belongs to the object, so you're never going to be able to manually release it. As its a singleton it doesn't matter if you don't own it because presumably next time you call it and need it in scope you'll use another convenience method and it will get instantiated again.
If you want to have ownership of the object then you will need to instantiate it as normal and then you will be able to retain and release it.
Also, read sergio's edit about it not being a "proper" singleton. :p
Also, if you can, convert to ARC and you won't have to worry about this!
U are doing it wrong. Consider:
If you calling activityViewForView multiple times, you won't get get the same object over and over again. It only would initialize a new object and give you the pointer to it!!!
To make this thing a singleton, you have to store the created object in a constant variable and make sure, you have a reference to this object all the time your app is running (for instance declare your pointer to this object in appDelegate).
Then every time you call activityViewForView you have to check the constant variable if it is pointing to a valid object. If so, return the valid object, if not, create it and store it in your constant static variable (creation is done only once).
If you do use ARC you're all set. If not, release your object (use dealloc method)