The following code compiles and executes as expected.
#import <objc/objc.h>
#import <Foundation/Foundation.h>
BOOL loopValue = YES;
#interface myThread:NSObject
-(void) enterThread: (NSArray *) elemt count: (NSString *) x;
#end
#implementation myThread
-(void) enterThread : (NSArray *) elemt
{
NSLog (#" Inside mythread ");
NSAutoreleasePool *pool = [[ NSAutoreleasePool alloc] init];
int i;
int cnt =10;
for(i=0; i<cnt; i++) {
NSLog (#"Number of elemennts in array %i ", [elemt count]);
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
}
loopValue = NO;
[pool drain];
}
#end
int main ( int argc, char ** argv)
{
NSAutoreleasePool *pool = [[ NSAutoreleasePool alloc] init];
// id tobj = [[myThread alloc] init];
id tobj = [ myThread new ];
NSLog (#"Starting New Thread ");
[NSThread detachNewThreadSelector:#selector(enterThread:) toTarget:tobj withObject:[NSArray arrayWithObjects:#"ram",#"20",nil]];
while(1)
if ( loopValue )
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]];
else
break;
NSLog (#".. Exiting.. \n");
[pool drain];
return 0;
}
MY Question:
While compilation i do get the following warnings..
mythread.m:24:1: warning: incomplete implementation of class ‘myThread’ [enabled by default]
mythread.m:24:1: warning: method definition for ‘-enterThread:count:’ not found [enabled by default]
While Execution
WARNING your program is becoming multi-threaded, but you are using an ObjectiveC runtime library .... Removed due to redability]hich does not have a thread-safe implementation of the +initialize method. ......
What am i dong wrong ? how to avoid both warning/runtime errors.
The method you declared is enterThread:count: but the method you implement is enterThread:. Also, that warning you are getting, I'm sure I've only seen that from the old GNUstep runtime… but I guess not.
Related
Here's a little experiment:
#interface Model : NSObject
#property (copy) NSString *value;
-(instancetype)initWith:(NSString *)value;
#end
#implementation Model
-(instancetype)initWith:(NSString *)value {
self = [super init];
self.value = value;
return self;
}
#end
#import <Foundation/Foundation.h>
#import "Model.h"
void experiment(Model *m);
int main(int argc, const char * argv[]) {
#autoreleasepool {
// insert code here...
NSLog(#"Hello, World!");
Model *ma = [[Model alloc] initWith:[[NSUUID UUID] UUIDString]];
experiment(ma);
NSLog(#"yyy %#", [ma value]);
}
return 0;
}
void experiment(ModelA *m) {
NSString *testValue = nil;
testValue = [m value];
NSLog(#"xxx %#", testValue);
}
When run, this produces the following:
Hello, World!
xxx 6005A7B0-F71C-4755-B1BF-792D6296B716
yyy 6005A7B0-F71C-4755-B1BF-792D6296B716
Program ended with exit code: 0
But suppose I make this line:
testValue = [m value];
part of a breakpoint:
And this changes everything:
Hello, World!
(__NSCFString *) $0 = 0x000000010071e220 #"1C0DCB39-BFBB-4E67-A041-E6B58615BDFD"
xxx 1C0DCB39-BFBB-4E67-A041-E6B58615BDFD
yyy 1C0DCB39-BFBB-4E67-A041-E6B58615BDFD
*** -[CFString release]: message sent to deallocated instance 0x10071e220
And a crash. I see what's happening--the string is released once we exit the function scope, and the second time when the Model object is destroyed, which is an overrelease. But why doesn't the breakpoint (or more precisely, the lldb expression inside the breakpoint) handle the reference count correctly?
I want to build a object that can run a loop in thread.
When I run a loop in thread using NSThread, sometimes works fine and sometimes the error message appear :
Uncaught exception NSInvalidArgumentException, reason: Tried to add nil value for key 'NSArgumentDomain' to dictionary.
How do I fix it? Or NSthread tutorial can be helpful.
#import <Foundation/Foundation.h>
#interface ThreadTest: NSObject
-(void) run;
-(void) goThread;
#end
#implementation ThreadTest
-(void) run {
#autoreleasepool {
int i;
for (i = 1; i < 5; i++) {
NSLog (#"Bar");
}
NSLog (#"end of loop");
}
}
-(void) goThread {
[NSThread detachNewThreadSelector: #selector(run)
toTarget: self
withObject: nil];
}
int main(void) {
#autoreleasepool {
ThreadTest *t = [[ThreadTest alloc] init];
[t goThread];
}
return 0;
}
NSDictionary crashes if you try to insert NIL to it. However, you can insert NSNULL argument to it.
So just make a check if your object is nil, insert NSNULL instead.
controlObject != nil ? controlObject : [NSNull null];
I am working on multi-threading using the following codes in XCode4:
#import <Foundation/Foundation.h>
bool trigger = false;
NSLock *theLock=[NSLock new];
#interface Metronome : NSObject
+(void)tick:(id)param;
#end
#implementation Metronome
+(void)tick:(id)param{
while(1)
{
NSLog(#"TICK\n");
usleep(1000000);
[theLock lock];
trigger = true;
[theLock unlock];
}
}
#end
int main()
{
[NSThread detachNewThreadSelector:#selector(tick:)
toTarget:[Metronome class] withObject:nil];
}
There is no compiling error, but during execution the console pops up the following warning:
objc[688]: Object 0x100300ff0 of class NSThread autoreleased with no pool
in place - just leaking - break on objc_autoreleaseNoPool() to debug
I'm not familiar with the memory management of obj-C. Can someone explain this to me? Thanks a lot!
you need a thread pool.
-(void)someMethod {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
//code that should be run in the new thread goes here
[pool release];
}
You could also considering using arc.
http://longweekendmobile.com/2011/09/07/objc-automatic-reference-counting-in-xcode-explained/
you have to create a NSAutoreleasePool for every thread that need invoke autorelease include main thread
int main()
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[NSThread detachNewThreadSelector:#selector(tick:)
toTarget:[Metronome class] withObject:nil];
[pool release];
}
#import <Foundation/NSArray.h>
#import <Foundation/NSString.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSEnumerator.h>
#import <stdio.h>
void print( NSArray *array ) {
NSEnumerator *enumerator = [array objectEnumerator];
id obj;
while ( obj = [enumerator nextObject] ) {
printf( "%s\n", [[obj description] cString] );
}
}
int main( int argc, const char *argv[] ) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSArray *arr = [[NSArray alloc] initWithObjects:
#"Me", #"Myself", #"I", nil];
NSMutableArray *mutable = [[NSMutableArray alloc] init];
// enumerate over items
printf( "----static array\n" );
print( arr );
// add stuff
[mutable addObject: #"One"];
[mutable addObject: #"Two"];
[mutable addObjectsFromArray: arr];
[mutable addObject: #"Three"];
// print em
printf( "----mutable array\n" );
print( mutable );
// sort then print
printf( "----sorted mutable array\n" );
[mutable sortUsingSelector: #selector( caseInsensitiveCompare: )];
print( mutable );
// free memory
[arr release];
[mutable release];
[pool release];
return 0;
}
this program compiled with oscv0.1.4 in windows.
it gives an error as shown below
Error: Parse error on line 6:
...import <stdio.h>
void print( NSArray
---------------------^
Expecting 'INTERFACE', 'IMPLEMENTATION', 'PROTOCOL', 'IMPORT', 'CLASS', 'DEFINE', 'EOF'
now i got one more error for the program shown below(it is another program)
#import "Forwarder.h"
#import "Recipient.h"
int main(void)
{
Forwarder *forwarder = [Forwarder new];
Recipient *recipient = [Recipient new];
[forwarder setRecipient:recipient]; //Set the recipient.
[forwarder hello];
[recipient release];
[forwarder release];
return 0;
}
error is
Error: Parse error on line 3:
...Recipient : Object
- (id)hello;
#end#i
----------------------^
Expecting '<', '{'
the format of your program must like the code shown below
here main must contain Main class
compare this with the link
http://code.google.com/p/oscompiler/downloads/list
#interface Main : NSObject { }
#end
#implementation Main
+(void)main {
NSLog(#"Hello world!");
}
#end
#import "movie.h"
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
// insert code here...
movie *obj = [[movie alloc]init];
[obj findinterestofnum1:(int)200 num2:(int)4 num3:(int)5];
SEL suf = #selector(findinterestofnum1: num2:num3:);
BOOL sul = [obj respondsToSelector:suf];
if(sul)
{
NSLog(#"It is implememted");
}
else
{
NSLog(#" It is not implemented");
}
NSLog(#"Hello, World!");
[pool drain];
return 0;
}
********-----
#interface movie : NSObject {
#private
}
-(void)findinterestofnum1:(int)p num2:(int)n num3:(int)r;
#end
*******-------
#import "movie.h"
#implementation movie
-(void)findinterestofnum1:(int)p num2:(int)n num3:(int)r
{
int a ;
a= (p*n*r/100);
NSLog(#"interest value is =%d",a);
}
- (void)dealloc
{
[super dealloc];
}
#end
i am trying to find whether method is implemented and if it is not it should print it is not implemented
#toddler, respondsToSelector just checks if the corresponding object can respond to that particular method. It doesn't do any checks on whether interface has that definition associated with it since it is a runtime check.
If you had removed the code from the implementation file (.m file) and not the interface, you would have got an error while executing it and you would have found that the BOOL sul is FALSE.